WeakReference 与 PhantomReference 加入ReferenceQueue时机的疑惑

阅读了 Guidelines for using the Java 2 reference classes  与 Understanding Weak References  之后,发现两篇文章关于 WeakReference 和 PhantomReference 何时被加入到 ReferenceQueue有些出入。也就是说到底是在引用的对象没有强引用时还是在引用的对象真正被回收时。于是写了如下程序进行验证:

package mypackage;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

class TestObj {
	
	//定义三种Reference用于保存指向本对象的Reference,从而在finalize中检验他们的get()值
	private SoftReference sr = null;
	private WeakReference wr = null;
	private PhantomReference pr = null;
	
	//定义ReferenceQueue用于在finalize中检验指向本对象的reference是否被加入了这个Queue
	private static ReferenceQueue rq = null;

	public static void setQueue(ReferenceQueue referenceQueue) {
		rq = referenceQueue;
	}

	public void setSr(SoftReference sr) {
		this.sr = sr;
	}

	public void setWr(WeakReference wr) {
		this.wr = wr;
	}

	public void setPr(PhantomReference pr) {
		this.pr = pr;
	}

	public void finalize() {
		
		//检验指向本对象的Reference的get()值
		if (null != sr)
			System.out.println("Soft Reference refers to " + sr.get()
					+ " in finalize().");
		if (null != wr)
			System.out.println("Weak Reference refers to " + wr.get()
					+ " in finalize().");
		if (null != pr)
			System.out.println("Phantom Reference refers to " + pr.get()
					+ " in finalize().");

		
		//验证是不是在对象finalize()的时候他的soft reference已经被加入至Queue中
		Reference r = rq.poll();

		while (null != r) {
			System.out.println(r.getClass().getName()
					+ " is added in the queue in finalize().");
			r = rq.poll();
		}

	}
}

public class Test {

	public static void main(String[] args) {
		{
           //用于传给三种Reference的强引用
			TestObj softObj = new TestObj();
			TestObj weakObj = new TestObj();
			TestObj phantomObj = new TestObj();

			ReferenceQueue rq = new ReferenceQueue();

		   //三种Reference指向三个不同的对象
			SoftReference sr = new SoftReference(softObj, rq);
			WeakReference wr = new WeakReference(weakObj, rq);
			PhantomReference pr = new PhantomReference(phantomObj, rq);
           
		   //将Reference传回给对应的对象
			softObj.setSr(sr);
			weakObj.setWr(wr);
			phantomObj.setPr(pr);
			
			//将ReferenceQueue传回给对象类
			TestObj.setQueue(rq);
            
			//删除强引用
			softObj = null;
			weakObj = null;
			phantomObj = null;
			System.gc();
			
			Reference r = null;

			// 为了确保对象被GC回收
			//******************************************
			
			while (null == r)
			{
				System.gc();
				r = rq.poll();
			}
			//******************************************

			while (null != r) {
				System.out.println(r.getClass().getName()
						+ " is added in the queue out of finalize().");
				r = rq.poll();
			}

		}

	}

}

 

但发现程序输出的结果是:

 

Phantom Reference refers to null in finalize().
Weak Reference refers to null in finalize().
Soft Reference refers to null in finalize().

 

这就有点让我纳闷了,到底是这些Reference没被加入Queue中呢还是内存中的对象没了被真正回收呢? 以/********包围起来的语句是我后来加上去的,是为了确保对象确实被回收,但发现这样的话程序就死循环了。

 

请高手解疑:)

你可能感兴趣的:(jdk,编程,sun)