不GC保证清除引用排队ReferenceQueue在拓了?
-
21-09-2019 - |
题
说有两个目的, A
和 B
, ,并有一个指 A.x --> B
, 和我们创建的,说, WeakReference
s到两个 A
和 B
, 与相关联 ReferenceQueue
.
假定这两个 A
和 B
变得遥不可及。凭直觉 B
不能被认为是无法到达之前 A
是。在这样的情况下,我们在某种程度上得到保证各自的参考文献将可在排队的直觉(拓扑结构时,有没有周期)的秩序 ReferenceQueue
?I.e。ref(A)之前参考(B)。我不知道-如果有什么的GC标志着一堆的对象为无法访问,然后排队他们在没有特别的了?
我是审查 Finalizer.java 番石榴,看到这段代码:
private void cleanUp(Reference<?> reference) throws ShutDown {
...
if (reference == frqReference) {
/*
* The client no longer has a reference to the
* FinalizableReferenceQueue. We can stop.
*/
throw new ShutDown();
}
frqReference
是PhantomReference的使用 ReferenceQueue
, 所以如果这是GC'ed,没有终结{弱、软、幻}引用可以活着,由于他们参考的队列。因此,他们必须GC'ed之前的队列本身可GC'ed-但是,我们得到保证,这些文献将可以排队的 ReferenceQueue
在为了他们得到"垃圾收集"(如果他们获得GC'ed一个由一)?代码暗示着存在某种保证,否则未经处理的引用理论上可以留在队列中。
感谢
解决方案
没有订购的保证。在这种情况下的Finalizer.java,螺纹可以关闭之前的所有引用的处理方式。请参阅的文档FinalizableReferenceQueue:
保持一个强大引到这个目的,直到所有相关的
- 对象已被最后定稿。如果这个目的是垃圾收集早些时候,
- 衬线将不会调用{@码finalizeReferent()}上
- 剩余的参考。
这是故意的行为。例如,我们使用FRQ清理地图项目时提到键和/或价值被清除。如果使用者不再具有参考地图,并反过来不再具有参考FRQ,有没有点处理那些参考文献。
其他提示
我敢肯定的是,答案是否定的。
在JVM规范说这大约释放方法:
在Java虚拟机上施加finalize方法调用没有顺序。终结可以称为以任何顺序甚至同时进行。 ( JVM规范2.17.7 )
从这个我推断有不能保证引用在拓扑顺序排队。
我觉得没有这样的保证。该GC本身不具备RAM的完整和直接视图(它不能,因为CPU只能看一次的几个字节的GC运行)。在您的例子,假设一个基本的“标志及掠” GC,机会是,A和B将被宣布在相同的标记阶段不可达,并没有特定的顺序扫在一起。维持拓扑顺序很可能是昂贵的。
至于Finalizer
,似乎它是为了仅通过FinalizableReferenceQueue
实例,该实例做了一些类加载器相关的魔法使用。该Finalizer
使用自己的设备时,从它在功能上取决于FinalizableReferenceQueue
变得本身不可达检测;这是一点,当它运行Finalizer
线程知道它应该退出。据我了解,如果该应用程序让GC回收FRQ,然后终结器线程将退出,任何引用入队“之后的” FRQ引用将不会被处理。这取决于拓扑顺序或缺乏,但我不能确定这是否是一个问题或没有。我认为该应用程序是不应该放弃其FRQ只要回收引用的对象的处理是很重要的。