Reference和ReferenceQueue的联动效果

最近在看LeakCanary原理解析的时候,发现可以创建一个ReferenceQueue队列;

使用 new WeakReference(object, ReferenceQueue) 之后,如果object对象被回收,那么WeakReference这个引用对象将会被添加到ReferenceQueue队列中

为此写个测试代码,记录一下。

public class LeakMemoryTest {
	//创建引用回收队列
	static ReferenceQueue<LeakMemoryTest> queue = new ReferenceQueue<>();
	//弱引用
	static WeakReference<LeakMemoryTest> ref;

	public static void main(String[] args) {
		//测试的回收对象
		LeakMemoryTest t = new LeakMemoryTest();
		//弱引用 关联 测试对象 和 回收队列
		ref = new WeakReference<>(t, queue);
		//日志打印 回收队列
		printQueue(queue);
		//将测试对象 置空, 如果不置空,对象不会被回收,最后引用对象也就不会出现在queue队列中
		t = null;
                System.out.println("release object.");
		Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				long millis = 2000L;
				int maxCount = 5;
				int current = 0;
				//判断弱引用中的对象是否被回收
				while (ref.get()!=null&& current < maxCount){
					System.out.println("sleep"+millis+"ms,start gc operation ");
					try {
						Thread.sleep(millis);
					} catch (InterruptedException e) {
						e.printStackTrace();
						break;
					}
					//开始 gc
					System.gc();
					current++;
				}
			}
		});
		thread.start();
		try {
			thread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//日志打印 回收队列
		printQueue(queue);
	}

	private static void printQueue(ReferenceQueue<LeakMemoryTest> queue){
		Reference<? extends LeakMemoryTest> temp;
		System.out.println("\nqueue ↓↓↓↓↓↓↓↓↓↓↓↓↓↓");
		do{
			temp = queue.poll();
			if(temp != null){
				System.out.println("reclaimed object :" + temp.toString()+" , ReferenceQueue object = "+temp.get());
			}
		}
		while (temp!=null);
		System.out.println("queue ↑↑↑↑↑↑↑↑↑↑↑↑↑↑\n");
	}
}
复制代码

最后运行结果:

queue ↓↓↓↓↓↓↓↓↓↓↓↓↓↓
queue ↑↑↑↑↑↑↑↑↑↑↑↑↑↑

release object.
sleep2000ms,start gc operation

queue ↓↓↓↓↓↓↓↓↓↓↓↓↓↓
reclaimed object :java.lang.ref.WeakReference@15db9742 , ReferenceQueue object = null
queue ↑↑↑↑↑↑↑↑↑↑↑↑↑↑
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享