それはそれらの有用性を低下させるので、私はそれについて疑問に思っていました. もしそうなら、主要なGCでメモリを弱く参照する方法はありますか?
6 に答える
javadoc には、s をクリア/破棄するための「タイムスケール」が具体的に記載されていませんWeakReference
。それはあなたの質問への答えになります(少なくとも理論的には)「それは実装に依存します」。実際、JLS の仕様と javadocs では、メジャー コレクションとマイナー コレクションについても言及されていません。トピック全体は、「実装の詳細」カテゴリにあります。
GC センシティブな参照が必要な場合は、SoftReference
代わりに a を使用する必要があります。それは次のように説明されています。
「ソフトに到達可能なオブジェクトへのすべてのソフト参照は、仮想マシンが OutOfMemoryError をスローする前にクリアされていることが保証されています。それ以外の場合、ソフト参照がクリアされる時間や、そのような参照のセットがただし、仮想マシンの実装では、最近作成された、または最近使用されたソフト参照をクリアすることにバイアスをかけることが推奨されます。"
他の場所では、ソフト参照は弱い参照よりも強いと説明されています。つまり、壊れる可能性が低いということです。たとえば、過度に熱心なガベージ コレクターによって。ただし、これはメジャー ガベージ コレクションとマイナー ガベージ コレクションのどちらについても言及していないことに注意してください。
更新Java 11 ソース ツリーのhttps://stackoverflow.com/a/16977182/139985で、次の (非常にもっともらしい!) クレームを調査しました。
マイナー コレクションは、若い空間内のすべてのオブジェクトを収集します。
WeakReference
若い空間のオブジェクトへのAは、マイナー GC で収集されます。
ネイティブの参照処理コードは複雑です。次のことを行う一般的なReferenceProcessor
クラスがあります。
Reference
GC が遭遇するオブジェクトを選択的に記録します。ReferenceProcessor::discover_reference
これを実現するためにGC コードが呼び出されます。- 検出されたオブジェクトを反復して
Reference
、参照を解除するかどうかを決定します。関連するReference
オブジェクトがそれぞれの参照キューに追加されます。
合併症は次のとおりです。
GC は を呼び出す場合と呼び出さない場合があります
ReferenceProcessor::discover_reference
。私が知る限り、ほとんどの (すべてではないにしても) GC はそれを呼び出しますが、確かなことはわかりません。ReferenceProcessor
には、参照と参照対象が異なる世代 (またはスパン) にある場合に対処するための異なるポリシーがあります。(参照が処理されない場合、参照対象は現在のコレクションで到達不可能なものとして扱われます。)
要するに、Reference
オブジェクトは通常、マイナー GC で処理されることを確認できます。ただし、特定の実際の動作は、世代/スパンの問題に依存するReference
場合があります。
(GC ログから特定の GC の一般的な動作を観察できるはずです。参照処理フェーズの統計またはタイミングを探してください。)
1 - 「スパン」という用語がコメントで使用されています。古い世代をいくつかの領域 (スパン) に分割し、別々に収集するコレクター (G1 など) に関連していると思います。
あなたが望むものに近いかもしれないSoftReferencesについて考えているかもしれません。
マイナー コレクションは、若い空間内のすべてのオブジェクトを収集します。若い空間のオブジェクトへの WeakReference は、マイナー GC で収集されます。Tenured スペース内のオブジェクトへの WeakReference は、Full GC などの Tenured コレクションで収集されます。ところで、保有スペースのみの同時収集を行うことができます。
WeakReference オブジェクトが Eden にあるかどうかによって異なります。マイナー コレクションは、Eden のオブジェクトのみを参照します。