回答:
Ethan Nicholas著、弱い参照の理解から:
弱い参照
弱参照は、簡単に言えば、メモリに残ってオブジェクトを強制的に十分な強さではありません参照です。弱い参照を使用すると、ガベージコレクターの機能を利用して到達可能性を判断できるため、自分で行う必要はありません。次のような弱参照を作成します。
WeakReference weakWidget = new WeakReference(widget);
そして
weakWidget.get()
、実際のWidget
オブジェクトを取得 するために使用できるコードの他の場所 。もちろん、弱い参照はガベージコレクションを防ぐのに十分強力ではないので、(ウィジェットへの強い参照がない場合)weakWidget.get()
突然戻り始めnull
ます。...
ソフトリファレンス
ソフト参照は、参照するオブジェクトを捨てることが少なく熱望していることを除いて、正確に弱い参照のようなものです。到達可能性が低いオブジェクト(オブジェクトへの参照が最も強い
WeakReferences
)は、次のガベージコレクションサイクルで破棄されますが、到達可能性が低いオブジェクトは、しばらくの間留まります。
SoftReferences
と動作が異なる必要はありませんWeakReferences
が、実際には、メモリが十分に 供給されている限り、ソフトに到達可能なオブジェクトは通常保持されます。これにより、上記のイメージキャッシュなどのキャッシュの優れた基盤になります。ガベージコレクターに、オブジェクトへの到達可能性(強力に到達可能なオブジェクトがキャッシュから削除されることはありません)とその悪さの両方を心配させることができるためです。彼らが消費しているメモリが必要です。
そして、ピーターケスラーはコメントに追加しました:
Sun JREはSoftReferencesをWeakReferencesとは異なる方法で処理します。利用可能なメモリに圧力がない場合、SoftReferenceによって参照されるオブジェクトを保持しようとします。1つの詳細:「-client」と「-server」のJREのポリシーは異なります。-clientJREはヒープを拡張するのではなくSoftReferencesをクリアすることを優先してフットプリントを小さくしようとしますが、-server JREはSoftReferencesをクリアするのではなく、(可能な場合は)ヒープを拡張することを優先することにより、パフォーマンスが向上します。1つのサイズですべてに対応できるわけではありません。
弱い参照は熱心に収集されます。オブジェクトが弱い到達可能性(弱い参照を介してのみ到達可能)をGCが検出した場合、GCはそのオブジェクトへの弱い参照をすぐにクリアします。そのため、プログラムは、クラスに関するキャッシュされたリフレクション情報やオブジェクトのラッパーなど、「関連付けられた情報」をプログラムが(強く参照して)保持しているオブジェクトへの参照を保持するのに適しています。それが関連付けられているオブジェクトがGCされた後に保持する意味はありません。弱参照がクリアされると、コードがどこかでポーリングする参照キューに入れられ、関連するオブジェクトも破棄されます。つまり、オブジェクトに関する追加情報を保持しますが、そのオブジェクトが参照するオブジェクトがなくなると、その情報は不要になります。実は 特定の状況では、WeakReferenceをサブクラス化して、オブジェクトに関連する追加情報をWeakReferenceサブクラスのフィールドに保持することもできます。WeakReferenceのもう1つの一般的な用途は、正規のインスタンスを保持するためにマップと組み合わせて使用することです。
一方、SoftReferencesは外部の再作成可能なリソースをキャッシュするのに適しています。GCは通常、リソースのクリアを遅らせるからです。ただし、OutOfMemoryErrorがスローされる前にすべてのSoftReferenceがクリアされることが保証されているため、理論的にはOOME [*]が発生することはありません。
典型的なユースケースの例は、ファイルのコンテンツの解析された形式を保持することです。ファイルをロードして解析し、解析された表現のルートオブジェクトへのSoftReferenceを保持するシステムを実装します。次にファイルが必要になったときに、SoftReferenceを介してファイルを取得しようとします。それを取得できる場合は、別のロード/パースを行わず、GCがその間にそれをクリアした場合は、リロードします。そうすることで、パフォーマンスの最適化に空きメモリを利用できますが、OOMEのリスクはありません。
次に[*]です。SoftReferenceを保持しても、それ自体でOOMEを引き起こすことはできません。一方、WeakReferenceを使用するタスクで誤ってSoftReferenceを使用する場合(つまり、オブジェクトに関連付けられた情報を何らかの方法で強く参照し、参照オブジェクトがクリアされたときに破棄する)、次のようにOOMEを実行できます。 ReferenceQueueをポーリングして関連オブジェクトを破棄するコードは、タイムリーに実行されない場合があります。
したがって、決定は使用法に依存します-構築するのにコストがかかりますが、他のデータから再構築できる場合は、ソフト参照を使用します-一部のデータの正規インスタンスへの参照を保持している場合、または「所有」せずにオブジェクトへの参照を持っている(そのため、オブジェクトがGCされないようにする)には、弱い参照を使用します。
WeakReference
それを使用する必要がある場所では、参照が範囲外になった後しばらくの間有効である可能性があるという事実は許容できるかもしれませんが、望ましくないということです。
WeakReference
です。詳しくはこちらをご覧ください:stackoverflow.com/a/46291143/632951
Javaでは ; 強いものから弱いものへの順序があります:強い、柔らかい、弱い、ファントム
強い参照は、 GCによってコレクションから参照されるオブジェクトを保護する通常の参照です。つまり、ガベージコレクションは行われません。
ソフト参照は、ガベージコレクタによって収集の対象であるが、そのメモリが必要になるまで、おそらく収集されることはありません。つまり、ガベージコレクションの前にOutOfMemoryError
。
弱参照は、 GCによってコレクションから参照されるオブジェクトを保護しない基準です。つまり、ストロングまたはソフトの参照がない場合、ガベージコレクションが行われます。
A ファントム参照は、オブジェクトへの参照は、想像線ことが確定された後の参照が、その割り当てられたメモリが再利用される前です。
類推: JVMが王国であり、オブジェクトが王国の王であり、GCがキング(オブジェクト)を殺そうとする王国の攻撃者であると仮定します。
until memory is available
は意味がありません。もしかしてis eligible for collection by garbage collector, but probably won't be collected until its memory is needed for another use
?
弱参照 http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html
原則: weak reference
ガベージコレクションに関連しています。通常、1つ以上のオブジェクトreference
はガベージコレクションの対象にはなりません。
上記の原則は、適用される場合には適用されませんweak reference
。オブジェクトに他のオブジェクトとの弱い参照しかない場合、ガベージコレクションの準備ができています。
以下の例を見てみましょうMap
。Keyがオブジェクトを参照する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
WeakHashMap
からエントリkey-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
ます。
NullPointerException
ではaMap.get().put(...)
。
WeakHashMap
例を指しているものです(それが弱い動作を示している最初の例であるため)。「WeakHashMap」のドキュメントを見てください。WeakHashMap "An entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. "
を使用することの全体的なポイントは、WeakReferenceを宣言/渡す必要がないことです。WeakHashMapは内部的にそれを行います。docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html
ソフトリファレンスとウィークリファレンスの本当の違いは、
ガベージコレクターはアルゴリズムを使用して、ソフトに到達可能なオブジェクトを再利用するかどうかを決定しますが、常に弱く到達可能なオブジェクトを再利用します。
SoftReference
キャッシュ用に設計されています。がWeakReference
他の方法では到達できないオブジェクトを参照していることが判明した場合、そのオブジェクトはすぐにクリアされます。SoftReference
そのままにすることができます。通常、空きメモリの量と、クリアする必要があるかどうかを判断するために最後に使用された時間に関連するアルゴリズムがいくつかあります。現在のSunのアルゴリズムでは、Javaヒープにメガバイトの空きメモリがあるため、何秒も使用されなかった場合、参照をクリアします(構成可能なサーバーHotSpotは、で設定された最大可能ヒープに対してチェックします-Xmx
)。SoftReference
sはOutOfMemoryError
、他に到達可能でない限り、スローされる前にクリアされます。
java.lang
。このような同義語の乱用は、何の役にも立ちません。
この記事は、強い参照、弱い参照、弱い参照、および幻の参照を理解するのに非常に役立ちます。
要約すると、
オブジェクトへの弱い参照のみがある場合(強い参照がない場合)、オブジェクトは次のGCサイクルでGCによって再利用されます。
オブジェクトへのソフト参照のみ(強い参照なし)がある場合、オブジェクトは、JVMがメモリを使い果たしたときにのみ、GCによって再利用されます。
つまり、強い参照には究極の力があります(GCで収集することはできません)。
ソフト参照は弱い参照よりも強力です(JVMがメモリ不足になるまでGCサイクルを回避できるため)。
弱参照は、ソフト参照よりも強力ではありません(オブジェクトが他の強参照を持たない場合は、GCサイクルを超えることができず、再利用されるため)。
レストランのアナロジー
これで、強い顧客(強い参照に類似)の場合、新しい顧客がレストランに来た場合や何が起こったとしても、テーブル(ヒープ上のメモリ領域)を離れることは決してありません。ウェイターはあなたにレストランを去るように言う(またはあなたに要求する)権利はありません。
あなたがソフト顧客(ソフト参照に類似)の場合、新しい顧客がレストランに来ても、ウェイターは新しい顧客を収容する他の空のテーブルがない限り、テーブルを離れるように求めません。(言い換えれば、ウェイターは、新しい顧客が参入し、この新しい顧客に他のテーブルが残っていない場合にのみ、テーブルを離れるように求めます)
あなたが弱い顧客(弱い参照に類似)である場合、ウェイターは彼の意志で(いつでも)レストランを出るように頼むことができます:P
ドキュメントごとに、実行中のGCによって緩いWeakReferencesをクリアする必要があります。
ドキュメントごとに、ルーズなSoftReferences は OOMがスローされる前にクリアされる必要があります。
それが唯一の本当の違いです。他のすべては契約の一部ではありません。(私は最新のドキュメントが契約であると仮定します。)
SoftReferencesは便利です。メモリ依存のキャッシュは、WeakReferencesではなくSoftReferencesを使用します。
weak_ref.get()
。になるnull
と、この期間の間にGCが実行されたことがわかります。
用として正しくない弱い参照の使用、リストは無限大です。
あなたは1を記述する必要はありません、というように優先-2 softreference実装するためのお粗末なハックはまだ期待通りにキャッシュがでクリアされるので、それは仕事をしませんすべてのスペアメモリがある場合でも、GCの実行を。フェイルについては、https: //stackoverflow.com/a/3243242/632951を参照して ください。(それに加えて、2レベル以上のキャッシュ優先度が必要な場合はどうなりますか?それでも、実際のライブラリが必要になります。)
既存のクラスのオブジェクトに関連付けるデータにお粗末なハック、まだあなたのGCは、あなたのweakreferencesが作成された後、休憩を取ることを決定したとき、それはメモリリーク(のOutOfMemoryError)を作成します。その上、それは醜いことを超えています:より良いアプローチはタプルを使うことです。
既存のクラスのオブジェクトにデータを関連付けるための粗末なハック。クラスはそれ自体をサブクラス化不可能にする神経を持ち、呼び出す必要がある既存の関数コードで使用されます。そのような場合、適切な解決策は、クラスを編集してサブクラス化できるようにするか、関数を編集してクラスではなくインターフェイスを取るようにするか、代替関数を使用することです。
equals()
が単なるオブジェクトID であるキャッシュについてはどうですか?ソフト参照は無駄に見えます。キーオブジェクトに到達できなくなると、そのマッピングを再度検索することはできないためです。
Javaの6種類のオブジェクト到達可能性状態:
詳細:https : //www.artima.com/insidejvm/ed2/gc16.html «折りたたむ
動作中のメモリ使用状況を示すために、プログラムの最後までそれらを保持することにより、重いオブジェクトの重い負荷の下で、Strong、Soft、Weak&Phantomリファレンスを使用して実験を行いました。次に、ヒープの使用状況とGCの動作を監視しました。これらのメトリックはケースバイケースで異なる場合がありますが、確かに高いレベルの理解を提供します。以下は調査結果です。
高負荷時のヒープとGCの動作
WeakReference:弱く参照されるだけのオブジェクトは、すべてのGCサイクル(マイナーまたはフル)で収集されます。
SoftReference:ソフト参照のみのオブジェクトが収集されるタイミングは、以下に依存します。
-XX:SoftRefLRUPolicyMSPerMB = Nフラグ(デフォルト値は1000、別名1秒)
ヒープ内の空きメモリの量。
例:
次に、SoftReferenceによってのみ参照されるオブジェクトは、最後にアクセスされた時間が10秒より大きい場合に収集されます。