JavaのReference

5296 ワード

jdk 1.2およびそれ以降に、強引用、ソフト引用、弱引用、虚引用の4つの概念が導入された。ネット上ではこの4つの概念に関する説明がたくさんありますが、概念的な一般論が多いです。今日はコードを結合して分析しました。まず定義と大体の説明を見に来ました。
1、強引用(StrongReference)
強引用はGCに回収されず、java.lang.refにも実際の対応タイプがない。例えば、Object obj=new Object();ここのobj引用は強い引用で、GCに回収されません。
2、ソフト引用(SoftReference)
ソフト引用はJVMがメモリ不足を報告する時にGCに回収されます。そうでなければ回収されません。このような特性のソフト引用はcachingとpoolingの中で広く使われています。ソフト引用の使い方:
    Object obj = new Object();

    SoftReference<Object> softRef = new SoftReference(obj);

    //    softRef.get()            

    Object objg = softRef.get();

3、弱引用(WeakReference)
GCが弱い参照対象を発見した場合、WeakReferenceが参照しているオブジェクトが解放されます。弱い引用の使用方法はソフト参照と似ていますが、回収戦略は異なります。
4、虚引用(PhotomReference)
GCが虚引用の対象を発見した時、PhotomReferenceの対象をReferenceQueの列に挿入します。この時PhotomReferenceが指す対象はGCに回収されていません。ReferenceQueがあなたの真の処理によって回収されるまで待つべきです。虚引用の使い方:
	Object obj = new Object();

	ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();

	PhantomReference<Object> phanRef = new PhantomReference<Object>(obj, refQueue);

	//   phanRef.get()             null

	Object objg = phanRef.get();

	//   obj   null, GC      ,GC  phanRef             refQueue  

	//   ,  phanRef    obj  ,    GC  ,        refQueue.poll  phanRef  

	//  GC        ,   JVM phanRef   refQueue     ,  GC   obj    

	Reference<? extends Object> phanRefP = refQueue.poll();
簡単な定義を見てから、コードを結合してテストします。強い引用はもちろん、ソフト引用の説明もよく分かります。鍵は「弱引用」と「虚引用」です。
弱引用:
	public static void main(String[] args) throws InterruptedException {

		Object obj = new Object();

		ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();

		WeakReference<Object> weakRef = new WeakReference<Object>(obj, refQueue);

		System.out.println(weakRef.get());

		System.out.println(refQueue.poll());

		obj = null;

		System.gc();

		System.out.println(weakRef.get());

		System.out.println(refQueue.poll());

	}

System.gc()はJVMにGCを実行する良い機会だと教えていますが、具体的な実行はJVMによって決定されますので、JVMがGCを実行すると決めた時に得られた結果は(実はこのコードは一般的にGCを実行します)です。
java.lang.Object@de6cednull nulljava.lang.ref.WeakReference@1fb8ee3
実行結果から、weakRef.get()を呼び出して、私達はobjオブジェクトを得ました。GCを実行していないので、refQue.poll()が戻ってきたnullは、obj=nullを返した時に、この時点では、ポートのOB jオブジェクトを参照していません。JVMはGCを実行しています。weakRef.get()を通じてnullに戻りました。refQue.poll()はWeakReferenceオブジェクトに戻りました。だからJVMはobjを回収してから、weakRefをrefQueキューに挿入しました。
虚引用:
	public static void main(String[] args) throws InterruptedException {

		Object obj = new Object();

		ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();

		PhantomReference<Object> phanRef = new PhantomReference<Object>(obj, refQueue);

		System.out.println(phanRef.get());

		System.out.println(refQueue.poll());

		obj = null;

		System.gc();

		System.out.println(phanRef.get());

		System.out.println(refQueue.poll());

	}
同様に、JVMがGCを実行した時、得られた結果は:
null null nulljava.lang.ref.PhantomReference@1fb8ee3
実行結果から、私たちが先に言ったのは間違いないということです。phanref.get()はどのような状況でもnullに戻ります。JVMがGCを実行して虚引用を発見した後、JVMはobjを回収せずにPhotomReferenceのオブジェクトを対応する虚引用キューrefQueに挿入し、refQue.pollを呼び出したら、Phoneオブジェクトに戻ります。pollメソッドはまずPhotomReferenceの保有チームをqueue(ReferenceQue)<?super T>)はNULLに設定され、NULLの対象はReferenceQueから継承され、enqueue(Reference paramReference)方法をreturn falseに上書きします。この時、Objは再びGCに発見された時、JVMはPhantomReferenceをNULLキューに挿入すると失敗してfalseに戻ります。実はこのコードを通して、私達もobjが回収されているかどうかは分かりませんが、PhotomReferenceのjavadocの注釈にはこう書かれています。
Onese the garbage collector decides that bajectobjis phantom-reachable、it is being enqueued on the coreress ponding queue、but its referent is not cleared.That is、the reference quexe the profereexe of proreemute aphrece
この話は簡単です。多くの人にもわかると思います。
GCが一つの「obj」を決定すると虚達到達であり、それは対応する隊列に入隊するが、その指代はクリアされていない。つまり、虚引用の引用列は、いくつかのアプリケーションコードによって明確に処理されなければならない。
弱い引用と虚引用の用途
ソフト引用は明らかにcachingとpoolingを作るのに使用できます。弱い引用と虚引用は?実は用途も大きいです。まず弱引用を見に来ました。例を挙げます。
 class Registry {

     private Set registeredObjects = new HashSet();



     public void register(Object object) {

         registeredObjects.add( object );

     }

 }

registeredObjectに追加したすべてのobjectはGCに回収されません。ここには強力な引用がありますので、register edbjectに保存します。
class Registry {

     private Set registeredObjects = new HashSet();



     public void register(Object object) {

         registeredObjects.add( new WeakReference(object) );

     }

 }
  現在GCがregister edbjectの中のobjectを回収したいならば、実現することができて、同様にHashMapを使って上述の効果を実現したいならば、1種のもっと良い実現はWeakhashMapを使うのです。
虚引用は?まず、javadocの部分説明を見てみます。
Photom references are useful for implementing cleanup operations that ar necessary before an object gets garbage-colleced.They are sometimes more freexible than thefinalize()method.
翻訳してみます
虚引用は、オブジェクトが回収される前に清掃作業を行う必要があります。彼らはフィナリゼよりも柔軟な方法を持っている場合があります。
明らかに、虚引用は対象が回収される前の整理作業に使用されることができる。