gpt4 book ai didi

java - 为什么ReferenceQueue总是空的?

转载 作者:行者123 更新时间:2023-11-30 03:44:50 25 4
gpt4 key购买 nike

我正在尝试使用 ReferenceQueue 来释放垃圾收集对象使用的资源。问题是我的引用队列始终为空,即使有证据表明引用的对象之一已被垃圾收集。这是一个非常简单、独立的 JUnit 测试,它说明了我正在尝试执行的操作(跟踪对象的删除):

@Test
public void weakReferenceTest() {
ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
Object myObject1 = new Object();
Object myObject2 = new Object();
WeakReference<Object> ref1 = new WeakReference<Object>(myObject1, refQueue);
WeakReference<Object> ref2 = new WeakReference<Object>(myObject2, refQueue);
myObject1 = null;

// simulate the application running and calling GC at some point
System.gc();

myObject1 = ref1.get();
myObject2 = ref2.get();
if (myObject1 != null) {
System.out.println("Weak Reference to MyObject1 is still valid.");
fail();
} else {
System.out.println("Weak Reference to MyObject1 has disappeared.");
}
if (myObject2 != null) {
System.out.println("Weak Reference to MyObject2 is still valid.");
} else {
System.out.println("Weak Reference to MyObject2 has disappeared.");
fail();
}
Reference<? extends Object> removedRef = refQueue.poll();
boolean trackedRemoval = false;
while (removedRef != null) {
if (removedRef == ref1) {
System.out.println("Reference Queue reported deletion of MyObject1.");
trackedRemoval = true;
} else if (removedRef == ref2) {
System.out.println("Reference Queue reported deletion of MyObject2.");
fail();
}
removedRef = refQueue.poll();
}
if (trackedRemoval == false) {
fail();
}
}

对我来说,这总是打印:

Weak Reference to MyObject1 has disappeared.
Weak Reference to MyObject2 is still valid.

...这很好,但测试总是失败,因为 trackedRemoval 最后为 false - ReferenceQueue 始终为空.

我使用的ReferenceQueue和/或WeakReference是错误的吗?我也尝试了 PhantomReference,但没有什么区别。

有趣的是,如果将单元测试转换为常规的 public static void main(String[] args) 方法,那么它的工作方式就像一个魅力!

谁能解释一下这种具体行为吗?我长期以来一直在寻找这个问题的答案。

最佳答案

对我来说这似乎是一种竞争条件。当GC确定myObject1引用的对象是GCable时,它会对其进行GC并将其从WeakReference中清除。然后,它将将该 WeakReference 添加到“待处理引用列表”中。有一个引用处理程序线程将从该列表中删除并添加到适当的ReferenceQueue。以上是支持javadoc的实现细节

At the same time or at some later time it will enqueue those newly-cleared weak references that are registered with reference queues.

当您的代码达到

Reference<? extends Object> removedRef = refQueue.poll();

引用处理程序线程不得将您的 WeakReference 添加到 ReferenceQueue 中,因此 poll 返回 null .

关于java - 为什么ReferenceQueue总是空的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25998367/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com