【问题标题】:What if a finalizer makes an object reachable?如果终结器使对象可访问怎么办?
【发布时间】:2011-04-18 00:15:23
【问题描述】:

在 Java 中,finalize 在对象即将被垃圾回收时调用(覆盖它),因此当它无法访问时。但是如果终结器使对象再次可访问,那会发生什么?

【问题讨论】:

    标签: java memory-management garbage-collection jvm finalizer


    【解决方案1】:

    是的,这就是你不使用终结器的原因(嗯,这是众多原因之一)。

    有一个参考集合可以做这些事情。稍后我会查找并在此处发布,但我认为它是 PhantomReference。

    是的,PhantomReference

    幻像引用对象,在收集器确定它们的引用对象可能会被回收后排队。幻影引用最常用于以比 Java 终结机制更灵活的方式调度事前清理操作。

    【讨论】:

    • 不,这是为什么不写一个非常糟糕的终结器的原因(如果没有足够的其他原因)。
    【解决方案2】:

    如果您仔细阅读 API 说明,您会发现终结器可以使对象再次可访问。该对象在(再次)无法访问之前不会被丢弃,但finalize() 不会被多次调用。

    【讨论】:

    • 实际上,终结器确实使对象在发现对象不可访问和运行终结器之间通过根引用强可访问。如果在此期间发现无法访问的对象成为对某个其他对象的唯一幸存引用,则在运行终结器或通过其他方式使该引用无效之前,该其他对象将无法收集。
    【解决方案3】:

    基本上,对象不会被垃圾回收。这称为对象复活。搜索那个词,你应该会得到一堆有趣的文章。正如 Jim 所提到的,重要的一点是终结器只会运行一次。

    【讨论】:

      【解决方案4】:

      对象在再次无法访问之前不会被收集。

      根据JavaDoc,finalize() 将不会被再次调用。

      【讨论】:

        【解决方案5】:

        它实际上做了另一遍检查并确保没有更多对该对象的引用。由于它在第二次通过时将无法通过该测试,因此您最终不会为该对象释放内存。

        因为对任何给定对象只调用一次finalize,下一次当它没有引用时,它只会释放内存而不调用finalize。一些关于定稿的好信息here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-09-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-23
          • 2012-08-23
          相关资源
          最近更新 更多