Java引用之虚引用
Java中的引用类型分为强引用、软引用、弱引用和虚引用,今天单说虚引用的使用场景。
虚引用(PhantomReference)
虚引用:简单来说就是对于引用对象来说如同虚设。如果一个对象仅持有虚引用,那么它和没有任何引用一样,在任何时候都有可能被垃圾回收器回收。
但是为什么开发这种引用,这种引用也是有用途的,主要用来跟踪对象被垃圾回收的活动。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。
根据官网的注释中看到使用虚引用进行清理要比Object的finalize方便灵活。
虚引用的使用
虚引用使用上需要注意几点:
必须和ReferenceQueue配合使用PhantomReference的get方法始终返回null当垃圾回收器决定对PhantomReference对象进行回收时,会将其插入ReferenceQueue中。下面就做个测试,为了触发GC,限制了堆的大小为56M,具体参数为:-Xms56M -Xmx56M 并添加了打印GC信息的参数-XX:+PrintGCDetails。
测试用例
代码很简单,特别说下ReferenceQueue的Remove方法是个阻塞方法。
程序的执行结果如下,当发生GC时从ReferenceQueue中获取到了PhantomReference对象,此时就可以做一些处理。
程序的执行结果
使用场景
网上很多对虚引用说明的文章,但是很少介绍真实的虚引用的使用场景,今天就介绍JDK中使用的场景
在NIO中可以使用堆外的内存,也叫直接内存,直接内存的回收就是使用的虚引用通知机制。
可以使用ByteBuffer的allocateDirect方法申请直接内存,具体代码如下:
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(10);
allocateDirect方法会创建一个DirectByteBuffer对象,下面就是构造方法:
DirectByteBuffer
在构造方法中,可以看到cleaner对象的创建,很明显这个对象就是执行清理工作的。详细查看Cleaner的源码前,先看Deallocator类,这个类就是一个Runnable,在run方法中通过Unsafe类的freeMemory方法释放内存。
Deallocator
类Cleaner继承于PhantomReference,其中有一个方法clean,这个方法执行清理工作,如果收到回收的信号,就会执行Deallocator的run方法。
clean方法
以上就是一个典型的虚引用的使用场景。
举报/反馈

Java猿猿

1893获赞 504粉丝
Java开发技术总结分享
科技领域爱好者
关注
0
0
收藏
分享