web-dev-qa-db-ja.com

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

誰かが3つの参照クラスの違いを説明できますか(またはニース説明へのリンクを投稿できますか)? SoftReference> WeakReference> PhantomReferenceですが、それぞれをいつ使用しますか? WeakHashMapはあるがSoftHashMapまたはPhantomHashMapはないのはなぜですか?

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

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であるかどうかを確認する必要がありますか(これは間違っていますが、should I do)?連発の質問は申し訳ありませんが、これらのReferenceクラスを理解するのに苦労しています...ありがとう!

79

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

ホストプロセスのメモリが不足するまで参照オブジェクトを存続させたい場合は、SoftReferenceを使用します。コレクターがメモリーを解放する必要があるまでオブジェクトはコレクションに適格ではありません。大まかに言って、SoftReferenceをバインドするとは、「もうできないまでオブジェクトをピン留めする」ことを意味します。

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

最後の1つ(PhantomReference)は特徴付けが困難です。 WeakReferenceと同様に、このようなバインドされたPhantomReferenceは、参照されるオブジェクトの存続期間に影響を及ぼしません。ただし、他の参照型とは異なり、PhantomReferenceを逆参照することもできません。ある意味では、発信者が知る限り、それが指し示すものを指し示していません。単に関連データを参照オブジェクトに関連付けることができます。PhantomReferenceが関連ReferenceQueueでキューに入れられたときに、後で検査して処理できるデータです。通常、PhantomReferenceから型を派生し、その派生型にいくつかの追加データを含めます。残念ながら、このような派生型を使用するためにダウンキャストが必要です。

サンプルコードでは、nullになる可能性のあるref参照(または、必要に応じて "変数")ではありません。むしろ、それは 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.
}
_
58
seh

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

PhantomHashMapはファントム参照に対して常にgetを返すため、nullはあまり機能しません。

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

getが非nullを返すことを常に確認する必要があります。 (注:Reference参照自体がnot _nullではないことを確認しません。)インターンされた文字列の場合、常にそうなりますが、(いつものように) " それについて。

Truong Xuan Tinhのコメントに記載されているように、ここにも言及する必要があります。 http://blog.yohanliyanage.com/2010/10/ktjs-3-soft-weak-phantom-references/ =

JRockit JVMはSun JVMとは異なる方法でweak/soft/phantom参照を実装します。

3
James L
_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()の呼び出しが重要です。

0
kopite