虚引用
在实际开发中没什么意义。其引用的对象相当于没有引用,比弱引用更弱,一般与引用队列相关联。
PhantomReference<String> phantomReference = new PhantomReference<String>("phantom", new ReferenceQueue<String>());
phantomReference.get()一直会返回空。
虚引用允许你知道具体何时其引用的对象从内存中移除,这是Java中唯一的方式。
虚引用可以避免很多析构时的问题,finalize方法可以通过创建强引用指向快被销毁的对象来让这些对象重新复活。然而,一个重写了finalize方法的对象如果想要被回收掉,需要经历两个单独的垃圾收集周期。
在第一个周期中,某个对象被标记为可回收,进而才能进行析构(折构方法不一定执行)。但是因为在析构过程中仍有可能这个对象会重新复活。这种情况下,在这个对象真实销毁之前,垃圾回收器需要再次运行。因为析构可能并不是很及时,所以在调用对象的析构之前,需要经历数量不确定的垃圾收集周期。这就意味着在真正清理掉这个对象的时候可能发生很大的延迟。这就是为什么当大部分堆被标记成垃圾时还是会出现烦人的内存溢出错误。
使用虚引用不能被用作让其指向的对象重生,所以其对象会在垃圾回收的第一个周期就将被清理掉。
显而易见,finalize方法不建议被重写。因为虚引用明显地安全高效,去掉finalize方法可以虚拟机变得明显简单。