当您丢弃对 SoftReference 的引用时,它的清除仍会放在 ReferenceQueue 上吗?

Dav*_*man 3 java garbage-collection soft-references java-memory-model

我想了解垃圾收集器在什么情况下会通知您清除软引用。文档清楚地表明它在可能发生 OOM 时发生,但是如果您完全丢弃引用,GC 会出现并收集 SoftReference 可能会注意到不存在其他强/软引用并清除内部引用值。

ReferenceQueue<Object> cleared = new ReferenceQueue<>();
Object X = new Object();
SoftReference<Object> Xs = new SoftReference<>(X, cleared);

Thread.sleep(10);
X = null;
Xs = null;

System.GC();
Thread.sleep(100);
Reference ref;
while ((ref = cleared.poll()) != null) {
   System.err.println(ref);
}
Run Code Online (Sandbox Code Playgroud)

那么关于这个队列的规则记录在哪里?一定有比我问的更多的极端情况,所以也许这个问题必须扩大一点。

Hol*_*ger 6

相关点可以在通知部分的包文档中找到:

注册的引用对象与其队列之间的关系是单方面的。也就是说,队列不会跟踪向其注册的引用。如果注册的引用本身变得不可访问,那么它将永远不会被排队。使用引用对象的程序有责任确保只要程序对其所指对象感兴趣,这些对象就保持可达。

所以答案很简单。由于您设置了唯一引用您的变量SoftReferenceto null,它永远不会被排队。它会被收集或清除,并不重要,因为你无法感知它。在实践中,典型的实现会像 Eugene 写的那样,垃圾收集器只遍历实时引用,而不关心剩余内存中存在什么样的垃圾。