【问题标题】:when finalize() is being executed? [duplicate]何时执行 finalize()? [复制]
【发布时间】:2013-12-09 06:21:06
【问题描述】:

在一次采访中我被问到,假设 JVM 在不使用类 A 的对象时运行 gc。

class A{
//some code here
protected void finalize(){
//code here
}
}

它是否保证 finalize() 的执行。我说是的

下一个问题是如果使用 Class A 的 obj,如果现在 JVM 运行 GC,它是否执行 finalize()。我说不,它不会执行这个finalize(),因为JVM不收集A的对象。

然而她没有发表任何评论,只是看起来很失望。

我解释错了吗?提前致谢

【问题讨论】:

标签: java jvm finalizer finalize


【解决方案1】:

不保证会调用类finalize() 方法。

finalize 的一般约定是JavaTM 虚拟机确定不再有任何方法可以让任何尚未访问该对象的线程访问该对象时调用它。死了,除非是由于某个其他准备完成的对象或类的完成而采取的行动

【讨论】:

  • 是的,finalize() 只会被 jvm 调用一次!
【解决方案2】:

Finalize 方法永远不能保证被调用。请参阅When is the finalize() method called in Java? 以获得对此的良好总结。

【讨论】:

    【解决方案3】:

    根据布鲁斯·埃克尔的说法:

    In Java, Objects do not always get garbage collected. 
    

    这通常意味着,即使您声明了 finalize() 方法,它也可能永远不会被调用。在这种情况下,您的清理例程将永远不会被执行。这完全取决于 JVM GC。 即使 GC 可能会运行,它也可能不会收集给定的对象。并且只要不再被引用的对象仍未被收集,它的finalize() 就永远不会被调用。

    此外,在程序终止之前,可能根本不会调用垃圾回收。在这种情况下,内存作为一个整体返回给操作系统,没有任何 GC。并且没有任何终结方法调用。

    所以,你的第一个问题的答案是

    你的第二个答案是对的。如果该对象仍在使用中,则无论 GC 是否运行,都无法将其收集(并调用 finalize()),除非您使用 WeakReference 或类似的东西。

    【讨论】:

      【解决方案4】:

      不能保证finalize() 方法会被调用。此外,您可以通过在finalize() 方法中为其分配链接来“恢复”组件,它将阻止垃圾收集。有趣的是 finalize() 永远不会再为这个对象调用,即使它被垃圾回收了。

      问题的第二部分:如果对象被使用,那么它不会被垃圾回收,因此finalize()不会被调用。

      【讨论】:

        猜你喜欢
        • 2019-07-22
        • 2010-09-06
        • 2013-11-21
        • 1970-01-01
        • 2013-06-06
        • 2013-05-01
        • 2021-07-18
        • 2015-11-03
        • 2011-06-14
        相关资源
        最近更新 更多