关于Reference与finalize的一点思考和研究
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于Reference与finalize的一点思考和研究相关的知识,希望对你有一定的参考价值。
参考技术A 最近读了寒泉子关于Finalizer的分享 JVM源码分析之FinalReference完全解读 - InfoQ结合之前对java引用类型的了解,突然想到几个开脑洞的问题:
我们是想验证各个引用类型进入队列的顺序,所以需要绑定到同一个ReferenceQueue,实现方式是利用反射把Finalizer里面的queue静态属性拿出来
另外FinalizerThread一直在跑,会造成干扰,我们要把这个线程stop掉,我们自己实现一个线程串行来消费队列里的元素
消费线程:
由于软引用比较难触发,所以实验一先排除它。我们写Main方法测试下
结果
可以看到第一次GC后先处理WeakReference,然后处理Finalizer,此时TestObject对象逃过了一次GC(因为刚从Finalizer静态链条上解除);第二次GC后PhantomReference进入队列;并且第一次GC后WeakReference和PhantomReference就get不到对象了
为了触发软引用,我们需要申请一块大内存,看下面改造后的main方法,再加上 -Xmx128m -Xms128m -Xmn28m 启动参数
运行结果
多执行几次还可能是下面结果
可以看到内存不足的时候把软引用和弱引用放到队列,(它们的先后顺序未知),然后Finalizer进入队列,此时TestObject对象逃过了一次GC,同实验一;然后再执行一次GC时PhantomReference进入队列,这时候对象才被真正回收。
实验二由于申请了大内存二导致GC,那么如果没有内存不足,但是存在三个引用会怎么样呢?我们修改下main方法试试
得到结果
如果没有Finalizer会怎么样呢?我们把实验二 TestObject 的 finalize方法删掉
结果
可以看到WeakReference和SoftReference放入队列后,PhantomReference也进入队列
到此基本上对整个过程比较清楚了,可以回答开篇的问题
对于finalize方法和虚引用资源回收的区别
最后还有一点疑问,WeakReference和SoftReference进入队列先后顺序怎么确定?这个比较奇怪,但篇幅有限暂时就不研究了。
以上是关于关于Reference与finalize的一点思考和研究的主要内容,如果未能解决你的问题,请参考以下文章