Javaの弱い参照
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における弱い参照という低レベルの概念を見て、これらを使用する最も一般的なシナリオに焦点を当てました。