81

誰かが3つのリファレンスクラスの違いを説明できますか(または素敵な説明へのリンクを投稿できますか)?SoftReference>> 、しかし、私はいつそれぞれを使用しますかWeakReferencePhantomReferenceなぜあるのに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クラスを理解するのに苦労しています...ありがとう!

4

4 に答える 4

60

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

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

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

最後の1つである<code>PhantomReferenceは、特徴付けが困難です。のようWeakReferenceに、そのような境界PhantomReferenceは参照されるオブジェクトの存続期間に影響を及ぼしません。ただし、他の参照型とは異なり、を逆参照することさえできませんPhantomReference。ある意味では、発信者が言うことができる限り、それはそれが指しているものを指していません。これは、いくつかの関連データを参照オブジェクトに関連付けることを可能にするだけです。データは、後でその関連データのPhantomReferenceキューに入れられたときに検査して処理することができReferenceQueueます。通常、1つは型を派生させ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.
}
于 2010-07-25T15:27:36.070 に答える
6

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

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

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

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

于 2010-07-25T15:25:10.293 に答える
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()は重要です。

于 2016-03-04T18:29:43.123 に答える