代码之家  ›  专栏  ›  技术社区  ›  Dimitris Andreou

GC是否保证清除的引用按拓扑顺序排队到ReferenceQueue?

  •  4
  • Dimitris Andreou  · 技术社区  · 16 年前

    假设有两个物体, A 和 B A.x --> B WeakReference 两个都是 A. 和 B ,具有关联的 ReferenceQueue .

    A. B 变得遥不可及。直观地 之前不能被视为无法访问 是在这种情况下,我们是否能以某种方式保证各自的引用将以直观的(没有循环时的拓扑)顺序排队 引用队列 ? 即参考(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 是对所使用的 引用队列 引用队列

    谢谢

    3 回复  |  直到 16 年前
        1
  •  3
  •   Bob Lee    16 年前

    没有订购保证。对于Finalizer.java,可以在处理所有引用之前关闭线程。有关FinalizableReferenceQueue,请参见文档:

    • 在所有相关联的

    • 参考资料已经定稿。如果这个对象是垃圾回收的,
    • 支持线程不会在上调用{@code finalizeReferent()}
    • 其余参考文献。

    这是故意的行为。例如,当对键和/或值的引用被清除时,我们使用FRQ来清除映射条目。如果用户不再有对地图的引用,反过来也不再有对FRQ的引用,那么处理这些引用就没有意义了。

        2
  •  4
  •   Stephen C    16 年前

    我很肯定答案是否定的。

    Java虚拟机对finalize方法调用不施加任何排序。终结器可以按任何顺序调用,甚至可以同时调用( JVM spec 2.17.7 )

        3
  •  1
  •   Thomas Pornin    16 年前

    我认为没有这样的保证。GC本身没有RAM的完整和即时视图(它不能,因为GC运行在一次只能查看几个字节的CPU上)。在您的示例中,假设一个基本的“mark&扫描“GC,很有可能A和B在同一标记阶段被宣布为不可到达,并且没有特定的顺序一起扫描。维持拓扑秩序可能是昂贵的。

    Finalizer FinalizableReferenceQueue 终结器 使用自己的设备检测 它在功能上依赖于它自己变得不可到达;这是运行的线程 终结器

    推荐文章