868

java.lang.ref.WeakReferenceとはどう違いjava.lang.ref.SoftReferenceますか?

4

12 に答える 12

981

Ethan Nicholas 著「Understanding Weak References」から:

弱参照

簡単に言えば、弱い参照とは、オブジェクトを強制的にメモリに残すほど強くない参照です。弱参照を使用すると、ガベージ コレクターの機能を利用して到達可能性を判断できるため、自分で行う必要はありません。次のような弱参照を作成します。

WeakReference weakWidget = new WeakReference(widget);

weakWidget.get()そして、実際の Widgetオブジェクトを取得するために使用できるコードの他の場所 。もちろん、弱い参照はガベージ コレクションを防ぐほど強力ではないため、(ウィジェットへの強い参照がない場合) が weakWidget.get()突然 を返し始めることがありnullます。

...

ソフト参照

ソフト参照は、それが参照しているオブジェクトを捨てようとしない点を除けば、弱参照とまったく同じです。わずかにしか到達できないオブジェクト (最も強力な参照は ですWeakReferences) は、次のガベージ コレクション サイクルで破棄されますが、わずかに到達可能なオブジェクトは、通常、しばらくの間残ります。

SoftReferencesは、 と異なる動作をする 必要はありませんWeakReferencesが、実際には、メモリが十分に供給されている限り、ソフトに到達可能なオブジェクトは通常保持されます。これにより、前述の画像キャッシュなどのキャッシュの優れた基盤になります。これは、ガベージ コレクターに、オブジェクトがどれだけ到達可能か (強く到達可能なオブジェクトはキャッシュから削除されない) と、それがどれほどひどいかの両方を心配させることができるためです。消費しているメモリが必要です。

Peter Kessler 氏はコメントで次のように付け加えました。

Sun JRE は、SoftReferences を WeakReferences とは異なる方法で扱います。使用可能なメモリに圧力がかかっていない場合は、SoftReference によって参照されるオブジェクトを保持しようとします。1 つの詳細: 「-client」JRE と「-server」JRE のポリシーは異なります。-client JRE は、ヒープを拡張するよりも SoftReferences をクリアすることを優先することで、フットプリントを小さく保とうとしますが、-server JRE は、 SoftReferences をクリアするよりもヒープを拡張する (可能であれば) ことを優先することで、パフォーマンスが向上します。1 つのサイズがすべてに適合するわけではありません。

于 2008-11-18T18:37:29.690 に答える
224

弱参照は熱心に収集されます。GC は、オブジェクトが弱い到達可能 (弱い参照を介してのみ到達可能) であることを検出した場合、そのオブジェクトへの弱い参照をすぐにクリアします。そのため、クラスに関するキャッシュされたリフレクション情報やオブジェクトのラッパーなど、プログラムが「関連情報」も保持する (強く参照される) オブジェクトへの参照を保持するのに適しています。関連付けられているオブジェクトが GC された後に保持する意味はありません。弱参照がクリアされると、コードがどこかでポーリングする参照キューにエンキューされ、関連するオブジェクトも破棄されます。つまり、オブジェクトに関する追加情報を保持しますが、参照先のオブジェクトがなくなると、その情報は必要なくなります。実際、特定の状況では、WeakReference をサブクラス化し、オブジェクトに関する追加情報を WeakReference サブクラスのフィールドに保持することもできます。WeakReference のもう 1 つの典型的な使用法は、正規のインスタンスを保持するための Maps と組み合わせたものです。

一方、SoftReferences は、通常、GC がそれらのクリアを遅らせるため、外部の再作成可能なリソースをキャッシュするのに適しています。ただし、OutOfMemoryError がスローされる前にすべての SoftReference がクリアされることが保証されているため、理論的には OOME[*] を引き起こすことはありません。

典型的なユースケースの例は、ファイルからコンテンツの解析された形式を保持することです。ファイルをロードして解析し、解析された表現のルート オブジェクトへの SoftReference を保持するシステムを実装します。次にファイルが必要になったときは、SoftReference を介してファイルを取得しようとします。それを取得できる場合は、別のロード/解析を回避し、その間に GC がそれをクリアした場合は、それをリロードします。そうすれば、パフォーマンスの最適化のために空きメモリを利用できますが、OOME のリスクはありません。

次に [*] です。SoftReference を保持しても、それ自体で OOME が発生することはありません。一方、WeakReference を使用することを意図したタスクに誤って SoftReference を使用した場合 (つまり、何らかの形で強く参照されているオブジェクトに関連付けられた情報を保持し、参照オブジェクトがクリアされたときにそれを破棄した場合)、次のように OOME に遭遇する可能性があります。 ReferenceQueue をポーリングし、関連付けられたオブジェクトを破棄するコードは、タイムリーに実行されない可能性があります。

したがって、決定は使用法に依存します-構築するのに費用がかかるが、それでも他のデータから再構築可能な情報をキャッシュしている場合は、ソフト参照を使用します-一部のデータの正規インスタンスへの参照を保持している場合、またはオブジェクトを「所有」せずにオブジェクトへの参照を持っている (したがって、GC されないようにする)、弱参照を使用します。

于 2008-11-18T18:27:02.863 に答える
182

Javaで; 強いものから順に、強い、弱い、弱い、ファントムがあります

強い参照は、GC によるコレクションから参照されたオブジェクトを保護する通常の参照です。つまり、ガベージ コレクションは行われません。

ソフト参照はガベージ コレクターによるコレクションの対象となりますが、メモリが必要になるまで収集されない可能性があります。つまり、前にガベージ コレクションが行われOutOfMemoryErrorます。

弱い参照とは、参照されるオブジェクトを GC によるコレクションから保護しない参照です。つまり、ガベージ コレクションは、Strong または Soft ref がない場合に発生します。

ファントム参照は、オブジェクトがファイナライズされた後、割り当てられたメモリが再利用される前にファントム参照されるオブジェクトへの参照です。

ソース

類推: JVM が王国であり、オブジェクトが王国の王であり、GC が王 (オブジェクト) を殺そうとする王国の攻撃者であるとします。

  • King がStrongの場合、GC は King を殺すことができません。
  • King がSoftの場合、GC は彼を攻撃しますが、King はリソースが利用可能になるまで王国を保護して支配します。
  • King がWeakの場合、GC は彼を攻撃しますが、保護なしで王国を支配します。
  • king がPhantomの場合、GC はすでに彼を殺していますが、king は彼の魂を介して利用可能です。
于 2015-08-03T10:39:35.950 に答える
80

弱参照 http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html

原則: weak referenceガベージ コレクションに関連しています。通常、1 つ以上のオブジェクトreferenceはガベージ コレクションの対象になりません。
の場合、上記の原則は当てはまりませんweak reference。オブジェクトが他のオブジェクトとの弱い参照しか持たない場合、そのオブジェクトはガベージ コレクションの準備ができています。

以下の例を見てみましょう: MapKey がオブジェクトを参照する with Objects があります。

import java.util.HashMap;   
public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> aMap = new 
                       HashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        System.out.println("Size of Map" + aMap.size());

    }
}

今、私たちが作ったプログラムの実行中にemp = null. このMapままでは鍵を握っても意味がないnull。上記の状況では、オブジェクトはガベージ コレクションされません。

WeakHashMap

WeakHashMapkey-to-value mappingsからエントリ ( ) を取得できなくなったときにエントリ ( ) が削除される場所Mapです。

WeakHashMapと同じ上記の例を示しましょう

import java.util.WeakHashMap;

public class Test {

    public static void main(String args[]) {
        WeakHashMap<Employee, EmployeeVal> aMap = 
                    new WeakHashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        int count = 0;
        while (0 != aMap.size()) {
            ++count;
            System.gc();
        }
        System.out.println("Took " + count
                + " calls to System.gc() to result in weakHashMap size of : "
                + aMap.size());
    }
}

出力: 次20 calls to System.gc()の結果に取りましたaMap size: 0.

WeakHashMapキーへの弱い参照のみがあり、他のMapクラスのような強い参照はありません。を使っていても値やキーが強く参照されている場合は注意が必要な場合がありますWeakHashMapこれは、オブジェクトをWeakReferenceでラップすることで回避できます。

import java.lang.ref.WeakReference;
import java.util.HashMap;

public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> map = 
                      new HashMap<Employee, EmployeeVal>();
        WeakReference<HashMap<Employee, EmployeeVal>> aMap = 
                       new WeakReference<HashMap<Employee, EmployeeVal>>(
                map);

        map = null;

        while (null != aMap.get()) {
            aMap.get().put(new Employee("Vinoth"),
                    new EmployeeVal("Programmer"));
            System.out.println("Size of aMap " + aMap.get().size());
            System.gc();
        }
        System.out.println("Its garbage collected");
    }
}

ソフト参照。

Soft Reference弱い参照よりわずかに強いです。ソフト参照はガベージ コレクションを許可しますが、他にオプションがない場合にのみ、ガベージ コレクターにそれをクリアするように要求します。

ガベージ コレクターは、弱い到達可能オブジェクトの場合のように、弱い到達可能オブジェクトを積極的に収集しません。代わりに、メモリが本当に「必要」な場合にのみ、弱い到達可能オブジェクトを収集します。ソフト参照は、ガベージ コレクターに対して、「メモリが不足していない限り、このオブジェクトを保持したいと考えています。しかし、メモリが非常に不足している場合は、先に進んで収集して対処します」と言う方法です。それと。" ガベージ コレクターは、スローする前にすべてのソフト参照をクリアする必要がありOutOfMemoryErrorます。

于 2013-10-17T03:05:44.993 に答える
55

ソフト参照と弱い参照の唯一の実際の違いは、

ガベージ コレクターはアルゴリズムを使用して、ソフト到達可能オブジェクトを再利用するかどうかを決定しますが、弱い到達可能オブジェクトは常に再利用します。

于 2012-04-03T15:23:54.727 に答える
28

SoftReferenceキャッシュ用に設計されています。WeakReference他の方法では到達できないオブジェクトを参照していることが判明すると、すぐにクリアされます。SoftReferenceそのままにしておくことがあります。通常、空きメモリの量と、クリアする必要があるかどうかを判断するために最後に使用された時間に関連するアルゴリズムがあります。現在の Sun のアルゴリズムでは、Java ヒープ上に解放されているメガバイトのメモリと同じ数の秒数が使用されていない場合、参照をクリアします (構成可能で、サーバーの HotSpot は、によって設定された最大可能ヒープに対してチェックします-Xmx)。s は、別の方法で到達可能でない限り、スローSoftReferenceされる前にクリアされます。OutOfMemoryError

于 2008-11-18T18:27:22.223 に答える
8

Java でのオブジェクトの到達可能性の状態には、次の 6 つのタイプがあります。

  1. 強く到達可能なオブジェクト - GCは、この種のオブジェクトを収集 (によって占有されていたメモリを再利用) しません。これらは、ルート ノードまたは別の強く到達可能なオブジェクト (つまり、ローカル変数、クラス変数、インスタンス変数など) を介して到達可能です。
  2. ソフトに到達可能なオブジェクト - GCは、メモリの競合に応じて、この種のオブジェクトを収集しようとする場合があります。これらは、1 つ以上のソフト参照オブジェクトを介してルートから到達可能です。
  3. 到達が困難なオブジェクト - GCはこの種のオブジェクトを収集する必要があります。これらは、1 つ以上の弱参照オブジェクトを介してルートから到達可能です。
  4. Resurrect-able objects - GC はすでにこれらのオブジェクトを収集中です。ただし、何らかのファイナライザーの実行によって、Strong/Soft/Weak のいずれかの状態に戻る可能性があります。
  5. 架空の到達可能なオブジェクト - GCは既にこれらのオブジェクトを収集する過程にあり、どのファイナライザーによっても復活できないと判断されました (それ自体が finalize() メソッドを宣言している場合、そのファイナライザーは実行されています)。これらは、1 つ以上のファントム参照オブジェクトを介してルートから到達可能です。
  6. 到達不可能なオブジェクト - オブジェクトは、強く、柔らかく、弱くも、ファントムも到達可能ではなく、復活することもできません。これらのオブジェクトは再利用の準備ができています

詳細については、https ://www.artima.com/insidejvm/ed2/gc16.html « 折りたたむ

于 2015-08-17T05:31:13.210 に答える
2

弱参照されたオブジェクトは、弱参照のみを持っている場合にのみ収集されることに注意してください。強参照が 1 つでもあると、弱参照がいくつあっても収集されません。

于 2016-05-15T04:32:48.163 に答える