1概要

この記事では、弱い参照という概念について、Java言語で説明します。

これらが何であるか、それらが何のために使用されているか、そしてそれらを適切に使用する方法について説明します。


2弱い参照

弱く参照されているオブジェクトは、弱く到達可能になったときにガベージコレクタによってクリアされます。

到達可能性が低いということは、

オブジェクトに強いリンクもリンクもないことを意味します。/java-soft-references[soft]それを指す参照

。目的は弱い参照をたどることによってのみ達することができます。

まず、ガベージコレクタが弱い参照をクリアするため、参照先にアクセスできなくなります。それから参照は参照キュー(関連するものがあれば)に置かれ、そこから取得できます。

同時に、以前は到達不可能だったオブジェクトが確定されます。


3.


ユースケース

Javaのドキュメントで述べられているように、

弱参照は正規化マッピングを実装するために最もよく使われます

。マッピングが特定の値のインスタンスを1つだけ保持している場合、そのマッピングは正規化されていると呼ばれます。新しいオブジェクトを作成するのではなく、マッピング内の既存のオブジェクトを検索して使用します。

もちろん、これらの参照の

最も知られている使い方はhttps://docs.oracle.com/javase/9​​/docs/api/java/util/WeakHashMap.html[

WeakHashMap

]クラス

です。これはhttps://docs.oracle.com/javase/9​​/docs/api/java/util/Map.html[

Map

]インタフェースの実装で、すべてのキーは指定されたキーへの弱い参照として格納されています。ガベージコレクタがキーを削除すると、このキーに関連付けられているエンティティも削除されます。

詳細については、リンクをチェックしてください:/java-weakhashmap[WeakHashMapのガイド]

それらが使われることができるもう一つの分野は

Lapsed Listener問題

です。

発行者(または件名)は、発生したイベントについて通知するために、すべての購読者(またはリスナー)への強力な参照を保持します。リスナーがパブリッシャーから正常に購読を解除できない場合、問題が発生します。

そのため、リスナーを強く参照しても出版社が利用できるので、リスナーはガベージコレクションできません。その結果、メモリリークが発生する可能性があります。

この問題の解決策は、購読を解除することなく前者をガベージコレクションすることを可能にするオブザーバへの弱い参照を保持しているということです(これは完全な解決策ではないので注意してくださいここでカバーされています。


4弱い参照を扱う

弱い参照はhttps://docs.oracle.com/javase/8/docs/api/java/lang/ref/WeakReference.html[

java.lang.ref.WeakReference

]クラスによって表されます。パラメータとして参照先を渡すことでそれを初期化することができます。

オプションで、https://docs.oracle.com/javase/8/docs/api/java/lang/ref/ReferenceQueue.html[

java.lang.ref.ReferenceQueue

]を指定できます。

Object referent = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();

WeakReference weakReference1 = new WeakReference<>(referent);
WeakReference weakReference2 = new WeakReference<>(referent, referenceQueue);

参照の参照先はhttps://docs.oracle.com/javase/8/docs/api/java/lang/ref/Reference.html#get–[

get

]メソッドで取得し、次のコマンドを使用して手動で削除できますhttps://docs.oracle.com/javase/8/docs/api/java/lang/ref/Reference.html#clear–[

clear

]メソッド:

Object referent2 = weakReference1.get();
weakReference1.clear();

この種の参照を安全に扱うためのパターンは

soft references

と同じです。

Object referent3 = weakReference2.get();
if (referent3 != null) {
   //GC hasn't removed the instance yet
} else {
   //GC has cleared the instance
}


5結論

このクイックチュートリアルでは、Javaにおける弱い参照という低レベルの概念を見て、これらを使用する最も一般的なシナリオに焦点を当てました。