Javaの参照クラスを理解する:SoftReference、WeakReference、およびPhantomReference


81

誰かが3つのリファレンスクラスの違いを説明できますか(または素敵な説明へのリンクを投稿できますか)?SoftReference> WeakReference>PhantomReferenceが、私は一つ一つを使用するとき?なぜあるのにWeakHashMapないのSoftHashMapPhantomHashMap

そして、次のコードを使用すると...

WeakReference<String> ref = new WeakReference<String>("Hello!");
if (ref != null) {                 // ref can get collected at any time...
    System.gc();                   // Let's assume ref gets collected here.
    System.out.println(ref.get()); // Now what?!
}

...何が起こるのですか?refすべてのステートメントの前にnullかどうかを確認する必要がありますか(これは間違っていますが、どうすればよいですか)?急いで質問して申し訳ありませんが、これらのReferenceクラスを理解するのに苦労しています...ありがとう!


1
なぜ、質問WeakHashMapがない、SoftHashMapまたはPhantomHashMap優れているのか、なぜ以前にこれに気づかなかったのか.. ??
Mehraj Malik 2017

1
ref != nullチェックは意味がありません。ref決してなりませんnull
ホルガー

Qに追加:strongRef --> weakRef --> objAobjAからの間接参照があるため、GCされるかどうかが決まりstrongRefます。
samshers

回答:


60

パッケージのJavaライブラリのドキュメントjava.lang.refは、3つの明示的な参照型の強度の低下を特徴としています。

SoftReferenceホストプロセスのメモリが不足するまで、参照されるオブジェクトを存続させたい場合は、を使用します。コレクターメモリーを解放する必要があるまで、オブジェクトは収集の対象になりません。大まかに言うと、バインドとSoftReferenceは、「もうできなくなるまでオブジェクトを固定する」という意味です。

対照的に、WeakReference参照されるオブジェクトの存続期間に影響を与えたくない場合は、を使用します。参照されているオブジェクトが存続している限り、それについて個別のアサーションを作成するだけです。オブジェクトの収集の適格性は、バインドされたWeakReferencesの存在に影響されません。オブジェクトインスタンスから関連プロパティへの外部マッピングのようなもので、関連オブジェクトが存続している限りプロパティを記録するだけでよいので、WeakReferencesとWeakHashMap。を使用すると便利です。

最後のものPhantomReference-特徴づけるのは難しいです。同様にWeakReference、このような境界PhantomReferenceは、参照されるオブジェクトの存続期間に影響を与えません。ただし、他の参照型とは異なり、を逆参照することもできませんPhantomReference。ある意味では、発信者が言うことができる限り、それはそれが指しているものを指していません。これは、いくつかの関連データを参照オブジェクトに関連付けることを可能にするだけです。データは、後でその関連データのPhantomReferenceキューに入れられたときに検査して処理することができReferenceQueueます。通常、型PhantomReferenceを派生させ、その派生型にいくつかの追加データを含めます。残念ながら、そのような派生型を利用するには、いくつかのダウンキャストが含まれます。

サンプルコードでは、refnullになる可能性があるのは参照(または、必要に応じて「変数」)ではありません。むしろ、Reference#get()nullになる可能性があるのは呼び出しによって取得された値です。nullであることが判明した場合は、手遅れです。参照されたオブジェクトはすでに収集されています。

final String val = ref.get();
if (null != val)
{
  // "val" is now pinned strongly.
}
else
{
  // "val" is already ready to be collected.
}

Qに追加:strongRef --> weakRef --> objAobjAからの間接参照があるため、GCされるかどうかが決まりstrongRefます。
samshers

私があなたの質問を正しく理解していれば、@ samshersobjAはゴミとして収集する資格があります。を固定しても、WeakReferenceそれがWeakReference指すオブジェクトには影響しません。
SEH

チェーンの上位に強い参照がないため、違いが生じます。以下のためにのでobjAごみすべき弱参照は、第1の右を除去しなければならない集め。そして、強い参照がGCedことに弱いrefは不適格作る弱い参照を指している
samshers

いいえ、WeakReference収集できるようにするために収集する必要はありませんobjAWeakReferenceキープしませんobjA生きています。むしろ、それは、objAその寿命に影響を与えることなく、生きている間に見つけて、コレクターがすでにそれを取り除いたときを検出する方法です。
SEH

6

リンク:https//community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references

PhantomHashMapファントム参照に対してget常に返さnullれるため、うまく機能しません。

キャッシュは難しいので、SoftHashMap思ったほどうまくいかないかもしれません。ただし、Googleのコレクションライブラリには、一般的な参照マップの実装が含まれていると思います。

get非を返すことを常に確認する必要がありますnull。(Reference参照自体がチェックされていないことに注意してくださいnull。)インターンされた文字列の場合は常にそうなりますが、(相変わらず)それについて「賢く」しようとしないでください。


リンクの有効期限が切れています。
Mehraj Malik 2017

@MehrajMalikリンクが修正されました。
トムホーティン-タックライン2017

Qに追加:strongRef --> weakRef --> objAobjAからの間接参照があるため、GCされるかどうかが決まりstrongRefます。
samshers


0
String str = new String("hello, world");
WeakReference<String> ref = new WeakReference<String>(str);
str = null;

if (ref != null) {                 
    System.gc(); 
    System.out.println(ref.get());
}

この場合、nullを出力します。ここでは、への呼び出しSystem.gc()が重要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.