Javaの弱い参照

Javaの弱い参照

1. 概要

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

これらが何であるか、それらが何に使用されるか、そしてそれらを適切に操作する方法を説明します。

2. 弱い参照

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

到達可能性が弱いということは、object has neither strong nor soft references pointing to itを意味します。 オブジェクトに到達するには、弱参照を走査する必要があります。

まず、ガベージコレクターは弱い参照をクリアするため、参照先にアクセスできなくなります。 次に、参照は参照キュー(関連付けられている場合)に配置され、そこから取得できます。

同時に、以前は弱到達可能であったオブジェクトがファイナライズされます。

3. ユースケース

Javaのドキュメントに記載されているように、weak references are most often used to implement canonicalizing mappings。 特定の値のインスタンスを1つしか保持していない場合、マッピングは正規化されたと呼ばれます。 新しいオブジェクトを作成するのではなく、マッピングで既存のオブジェクトを検索して使用します。

もちろん、most known use of these references is the WeakHashMap class。 これは、Mapインターフェースの実装であり、すべてのキーが特定のキーへの弱参照として格納されます。 ガベージコレクターがキーを削除すると、このキーに関連付けられているエンティティも削除されます。

詳細については、our guide to WeakHashMapを確認してください。

それらを使用できるもう1つの領域は、the Lapsed Listener problemです。

パブリッシャー(またはサブジェクト)は、発生したイベントについて通知するために、すべてのサブスクライバー(またはリスナー)への強い参照を保持します。 The problem arises when a listener can’t successfully unsubscribe from a publisher.

したがって、パブリッシャーはリスナーへの強い参照を引き続き利用できるため、リスナーをガベージコレクションすることはできません。 その結果、メモリリークが発生する可能性があります。

この問題の解決策は、オブザーバーへの弱参照を保持しているサブジェクトであり、サブスクライブを解除しなくても前者をガベージコレクションできるようにすることができます(これは完全な解決策ではなく、そうでない他のいくつかの問題が発生することに注意してください)ここで説明します)。

4. 弱参照の操作

弱参照はjava.lang.ref.WeakReferenceクラスで表されます。 リファレントをパラメーターとして渡すことで初期化できます。 オプションで、java.lang.ref.ReferenceQueueを指定できます。

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

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


参照の指示対象は、getメソッドでフェッチし、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の弱参照という低レベルの概念を見て、これらを使用する最も一般的なシナリオに焦点を当てました。