JAvaリファレンス説明:java強リファレンス、ソフトリファレンス、弱リファレンス、虚リファレンス

9870 ワード

一.この知識の目的は何ですか.
メモリの漏洩とOOMの問題を解決する合理的な使用リファレンスは、ごみ回収器がJavaメモリをよりよく管理するのに役立ちます.
二.この知識の応用場面は何ですか.
メモリ漏洩の原因となるシーンでoomは、ソフトリファレンス、弱いリファレンス、ダミーリファレンスのため、関連するオブジェクトにリファレンスが発生しないため、関連するオブジェクトのライフサイクルに影響を与えません.
特に、世紀のプログラム設計では弱引用や虚引用はあまり使われず、ソフトを使うことが多い.これは、ソフト引用がJVMのゴミメモリの回収速度を速め、システムの運行安全を維持し、メモリオーバーフロー(OutOfMemory)などの問題の発生を防ぐことができるからである.
三.この知識の基本概念
1.強引用(StrongReference)
コードString s=「abc」の変数sが文字列オブジェクト「abc」の強い参照であるなど、プログラミング中に使用される最も簡単な参照です.強い参照によって指向されるオブジェクトは、プログラムに必要なゴミ回収器によって回収されません.
2.ソフトリファレンス(SoftReference)
 解ソフトリファレンスは、Javaでjava.lang.ref.SoftReferenceクラスで表される、役に立つが必要ではないオブジェクトを記述するために使用されます.ソフトリファレンスが関連付けられているオブジェクトについては、メモリが不足している場合にのみJVMがそのオブジェクトを回収します.したがって、この点はOOMの問題を解決するのによく用いられ、この特性は、ウェブキャッシュ、ピクチャキャッシュなどのキャッシュを実現するのに適している.
  ソフトリファレンスは、JVMによってリファレンスされたオブジェクトが回収されると、それに関連付けられたリファレンスキューに追加されるリファレンスキュー(ReferenceQueue)と組み合わせて使用できます.  
3.弱引用(WeakReference)
弱い参照を解くことも、必要でないオブジェクトを記述するために使用されます.JVMがゴミ回収を行うと、メモリが十分であるかどうかにかかわらず、弱い参照に関連付けられたオブジェクトが回収されます.Javaではjava.lang.ref.WeakReferenceクラスで表されます.
4.ダミーリファレンス(PhantomReference)
仮想リファレンスは、前のソフトリファレンス、弱いリファレンスとは異なり、オブジェクトのライフサイクルに影響しません.Javaではjava.lang.ref.PhantomReferenceクラスで表されます.オブジェクトがダミーリファレンスに関連付けられている場合、リファレンスが関連付けられていない場合と同様に、ゴミ回収器によっていつでも回収される可能性があります.
  解注意すべきは、ダミーリファレンスはリファレンスキューに関連付けて使用する必要があります.ゴミ回収器がオブジェクトを回収する準備をしているときに、ダミーリファレンスがあることに気づいたら、このダミーリファレンスを関連付けられたリファレンスキューに追加します.プログラムは、参照キューに虚参照が含まれているかどうかを判断することによって、参照されたオブジェクトがゴミ回収されるかどうかを知ることができる.プログラムが虚参照が参照キューに追加されていることを発見した場合、参照されたオブジェクトのメモリが回収される前に必要な行動をとることができます.
四.一つのdemo
public class Demo2 {
    public static void main(String[] args) {
        //    ,    ,   
        String hello = new String("hello");//   
        SoftReference sr = new SoftReference(hello);
        hello = "111";
        System.out.println(sr.get());

        //    ,    ,   
        String hello1 = new String("hello");
        WeakReference<String> sr1 = new WeakReference<String>(hello1);
        hello1 = "222";
        System.out.println(sr1.get());
        System.gc();
        System.out.println(sr1.get());

        //    ,   
        ReferenceQueue<String> queue = new ReferenceQueue<>();
        String hello2 = new String("hello");
        PhantomReference<String> pr = new PhantomReference<>(hello2, queue);
        hello2 = "333";
        System.out.println(pr.get());
    }



}

五.1つの適用シーン
以下に例を挙げると、あるアプリケーションが大量のローカルピクチャを読み取る必要がある場合、読み取りピクチャがハードディスクから読み出されるたびにパフォーマンスに深刻な影響を及ぼすが、すべてメモリにロードされるとメモリがオーバーフローする可能性があるため、ソフトリファレンスを使用してこの問題を解決することができる.
1つのHashMapでピクチャのパスと対応するピクチャオブジェクトに関連付けられたソフトリファレンスとのマッピング関係を保存し、メモリが不足している場合、JVMはこれらのキャッシュピクチャオブジェクトが占有する空間を自動的に回収し、OOMの問題を効果的に回避する.Android開発では大量の画像ダウンロードによく使われる.
次のコードはブログから抜粋しています.http://blog.csdn.net/arui319/article/details/8489451
.....
private Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();
<br>....
public void addBitmapToCache(String path) {

        //     Bitmap  

        Bitmap bitmap = BitmapFactory.decodeFile(path);

        //     Bitmap  

        SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap);

        //       Map     

        imageCache.put(path, softBitmap);

    }

 public Bitmap getBitmapByPath(String path) {

        //          Bitmap  

        SoftReference<Bitmap> softBitmap = imageCache.get(path);

        //          

        if (softBitmap == null) {

            return null;

        }

        //   Bitmap  ,        Bitmap   ,    

        Bitmap bitmap = softBitmap.get();

        return bitmap;

    }

六.java参照に対する理解
1.JavaリファレンスとJavaゴミ回収メカニズムの関係
Java仮想マシン(JVM)がメモリが不足していると感じた場合、ゴミ回収操作(GC)がトリガーされ、不要なオブジェクトが消去され、メモリが解放されます.しかし、どのようにして対象がゴミかどうかを判断しますか?1つの方法は、オブジェクトへの参照数を計算することです.参照数が0の場合、オブジェクトはゴミ(Threadオブジェクトは例外)になります.そうしないと、回収できません.しかし、参照数が0のオブジェクトをすべて回収した場合、メモリの要件を満たすことができない場合はどうしますか?Javaはリファレンスを4種類に分けており,ゴミ回収器は弱いリファレンスのみのオブジェクトを回収しようと試みる.  解は1つのオブジェクトの参照によって(Reachable)強度に達することができ、強いから弱いまで5種類に分けられ、以下のようになる.
  • Strong Reachableは、1つのスレッド内で直接参照する必要がなく、新しく作成されたオブジェクトは強力です.
  • 軟可達(Soft Reachable)は強達ではないが、軟参照(SoftReference)によって達できる.
  • 弱達(Soft Reachable)は強達でも軟達でもないが、弱引用(WeakReference)で達できる.
  • 虚数到達(Phantom Reachable)は、強到達でも軟到達でも弱到達でもないが、虚数参照(PhantomReference)によって到達することができる.
  • は、オブジェクトを参照することはできません.Javaごみ回収器は、強度の低いオブジェクトを優先的にクリーンアップすることがわかりやすい.他にも2つの重要な点があります.強いものは必ずクリーンアップされません.JVMはout of memoryを投げ出す前に、すべてのソフトリファレンスオブジェクト
  • をクリーンアップします.
    2.私の理解と悟り
      リファレンスはjavaにおいて非常に重要な概念であり、高品質のコードを書くことにとって非常に重要であることを理解しなければならない.そうしないと、書かれたコードは各種のメモリ漏洩であり、oomは知らない.この概念を理解するには、メモリの割り当てやゴミの回収など、jvmについて理解する必要があります.
  • ローカル変数は、ローカル変数がその作用領域内でのみ有効であるため、外部オブジェクト(すなわち、外部オブジェクトに割り当てられたメモリ領域)への参照を持たない.
  • メンバー変数は、必ずしも外部オブジェクト(すなわち、外部オブジェクトが割り当てられたメモリ領域)への参照を持つ必要はありません.この問題は、メンバー変数が内部クラスである場合にのみ発生します.メンバー変数が他のファイルに定義されている場合、メモリ漏洩は発生しません.メモリ漏洩の可能性があるかどうかに注意してください.内部クラスは、外部クラスへの参照を保持します.すなわち、1内部クラスオブジェクトの作成は外部クラスオブジェクトに依存する.2内部クラスオブジェクトは外部クラスオブジェクトへの参照を持つ.
  • 参照の簡単な理解:A a=new A()で、javaはスタックに領域を割り当て、スタックにある参照aをこの領域に指し示す.
  • 実はごみ回収メカニズムが注目しているのは、スタック内の割り当てられた領域が他の参照変数に指さされているかどうかであり、誰も指ささなければ回収できる.
  •          //    ,    ,   
            String hello = new String("hello");//   
            SoftReference sr = new SoftReference(hello);
            hello = null;
            System.out.println(sr.get());
    

    上記のコードに示すように、helloはスタックにメモリを割り当て、ソフトリファレンスもこのメモリを指しています.これはhelloがこのポインタをクリアしたため、このメモリ領域は現在ソフトリファレンスのみが彼を指しています.このとき、このメモリ領域はすぐに回収されません.JVMがメモリを必要としない限り、回収されません.
            //    ,    ,   
            String hello1 = new String("hello");
            WeakReference<String> sr1 = new WeakReference<String>(hello1);
            hello1 = null;
            System.out.println(sr1.get());
    

    上記のコードに示すように、hello 1はスタックにメモリを割り当て、ソフトリファレンスもこのメモリを指している.これはhello 1がこのポインタをクリアしたため、このメモリ領域は現在弱いリファレンスのみが彼を指している.JVMがゴミ回収を行うと、メモリが十分かどうかにかかわらず、このメモリ領域を回収する.
            //    ,   
            ReferenceQueue<String> queue = new ReferenceQueue<>();
            String hello2 = new String("hello");
            PhantomReference<String> pr = new PhantomReference<>(hello2, queue);
            hello2 = null;
            System.out.println(pr.get());
    

    上記のコードに示すように、hello 2はスタックにメモリを割り当て、ソフトリファレンスもこのメモリを指しています.これはhello 2がこのインデックスをクリアしたため、このメモリ領域は現在、ダミーリファレンスのみが彼を指していますが、ダミーリファレンスはリファレンスが関連していないのと同じように、このメモリ領域はいつでもゴミ回収器によって回収される可能性があります.5.後で対象が回収されるかどうかを話し、割り当てられた領域が回収されるかどうかを提案し、問題の核心をより直接指す.