ホームページ  >  記事  >  Java  >  Java 開発における強参照、ソフト参照、弱参照、仮想参照

Java 開発における強参照、ソフト参照、弱参照、仮想参照

无忌哥哥
无忌哥哥オリジナル
2018-07-23 10:05:431495ブラウズ

Java には GC 自動リサイクル機構があるため、オブジェクトが保持する参照を強度の順に強参照、弱参照、仮想参照に分けて使用することができます。ライフサイクルを超えたインスタンスを迅速にリサイクルするための GC により、マシンのメモリ使用量が動的に低レベルになるため、不適切な使用によりメモリ リークが発生し、マシンのメモリが枯渇してダウンタイムが発生する可能性があります。書き込み内容を明確に制御する必要があります。プログラムの特性は、少なくとも現在制御可能と考えられる制御可能な状態に維持される必要があります。まず引用の分類を理解してから、使用シナリオを検討してみましょう。

1. 強参照

通常、次のような強参照を使用します。

Map<String, Object> param = new HashMap<String, Object>(16);

上記の形式の参照は、参照が有効なライフサイクル内にある限り、GC は使用できません。もちろん、参照自体を再利用することはできません。強参照の使用とルールは自明です。

2. ソフト参照

まず、ソフト参照がどのように使用されるかを見てみましょう:

Map<String, Object> param = new HashMap<String, Object>(16);
param.put("status", 1);
SoftReference> softRef = new SoftReference>(param);
System.out.println(softRef.get().get("status"));

使用法はもう 1 つありますが、参照という点では、ソフト参照は強参照に次いで理解しやすいものです。仮想環境でのみ使用されます。マシンがメモリが不足していると判断した場合、ソフト参照の参照がまだライフサイクル内であっても、この時点でソフト参照が指すヒープ領域は強制的に回収されます。 get() を呼び出すと null が返されるため、通常の状況では、ソフト参照のパフォーマンスは強参照のパフォーマンスと異なります。仮想マシンがメモリが不足していると判断した場合にのみ、ソフト参照はその特性を反映します。 。

3. 弱参照

弱参照の使い方:

Map<String, Object> param = new HashMap<String, Object>(16);
param.put("status", 1);
WeakReference> weakRef = new WeakReference>(param);
System.out.println(weakRef.get().get("status"));

弱参照はソフト参照より劣った参照です。参照カウンタは計算に含まれるため、インスタンスに強参照がなく、弱参照だけがある場合、GC がリサイクルされたかどうかに応じて null が返される可能性があります。上記の例では、強参照と弱参照の両方が存在します。見てみましょう。弱い参照のみが存在します:

WeakReference<Map<String, Object>> weakRef = new WeakReference<Map<String, Object>>(new HashMap<String, Object>(16));
System.gc();
System.out.println(weakRef.get());

この時点では、出力される値は null です。これは、弱い参照が GC 参照テクノロジに対して有効ではないことを意味します。

4. 仮想参照

仮想参照の使用法は上記とは少し異なります。GC がオブジェクトをリサイクルする準備をしているときに、仮想参照がまだ存在することが判明すると、その仮想参照が参照に追加されます。それに関連付けられたキュー。 『Java 仮想マシンの詳細な理解: JVM の高度な機能とベスト プラクティス』の第 2 版のセクション 3.2.3 には、「仮想参照は、ゴースト参照またはファントム参照とも呼ばれます。最も弱い参照関係。オブジェクトに仮想参照があるかどうかは、その存続期間にはまったく影響しません。オブジェクトに仮想参照の関連付けを設定する唯一の目的は、システム通知を受信した後にリサイクルできるようにすることです。 JDK 1.2 では、仮想参照を実装するために PhantomReference クラスが提供されています。まず、仮想参照タイプの定義を見てみましょう:

public class PhantomReference<T> extends Reference<T> {

    public T get() {
        return null;
    }

    public PhantomReference(T referent, ReferenceQueue<? super T> q) {
        super(referent, q);
    }

}

コンストラクターが 1 つだけあり、参照キューを 1 つ指定する必要があることがわかります。次のコードは、デモ:

ReferenceQueue<Map<String, Object>> q = new ReferenceQueue<Map<String, Object>>();
PhantomReference<Map<String, Object>> phantomRef = new PhantomReference<Map<String, Object>>(new HashMap<String, Object>(16), q);
System.gc();
Thread.sleep(1000);
System.out.println(phantomRef.get());
System.out.println(q.poll());

出力された結果は null であり、PhantomReference のインスタンスです。これは、仮想参照を通じてオブジェクト インスタンスを取得できないことと、参照が参照キューに追加されたという事実を検証します。

以上がJava 開発における強参照、ソフト参照、弱参照、仮想参照の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。