我一直在阅读这篇关于 PhantomReference https://www.baeldung.com/java-phantom-reference的文章,并在那里找到了简化的示例代码:
public static void main(String[] args) throws InterruptedException {
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
Object object = new Object();
PhantomReference<Object> phantomReference = new PhantomReference<>(object, referenceQueue);
object = null;
System.gc();
Thread.sleep(1_000);
System.out.println("isEnqueued() after GC: " + phantomReference.isEnqueued());
Reference reference = referenceQueue.poll();
if(reference != null) {
System.out.println("isEnqueued() after poll(): " + phantomReference.isEnqueued());
}
}
这是输出:
isEnqueued() after GC: true
isEnqueued() after poll(): false
所以一切都按预期工作,对对象的强引用设置为 null ,由 GC 检测到,幻像引用被添加到队列中。
现在在那篇文章中他们说:“垃圾收集器在执行其引用对象的 finalize 方法后向引用队列添加一个幻像引用。这意味着该实例仍在内存中。”
所以我想做一个测试并覆盖 finalize 方法,如:
Object object = new Object() {
@Override
protected void finalize() throws Throwable {
System.out.println("finalize()");
}
};
但是输出不同,幻影引用不再添加到队列中:
finalize()
isEnqueued() after GC: false
有人可以解释为什么在此更改后输出不同以及如何更改此代码以便将幻像引用添加到队列中吗?
我一直在 JDK 8 和 11 上对此进行测试,两个平台上的结果相同。