首页 > 解决方案 > 垃圾回收期间何时调用 finalize()?

问题描述

从 :

https://www.baeldung.com/java-memory-management-interview-questions的 Q11

当一个对象符合 GC 条件时,垃圾收集器必须对其运行 finalize();此方法保证只运行一次,因此收集器将对象标记为已完成并让它休息直到下一个周期。

我有几个问题要问:

PS:我知道 finalize() 最终在 Java 9 中被弃用了。感谢决定这样做的好灵魂。

标签: javamemory-managementgarbage-collectionfinalize

解决方案


是在标记阶段,垃圾收集器会调用 finalize() 方法吗?

依赖于实现,但通常没有。GC 完成后由后台线程调用终结器。

请记住,GC 可能是一个停止世界的事件,并且应该尽可能短。终结器方法可能很慢,因此不应在 GC 期间调用它们。

为什么它要休息到下一个周期?

在高级(简化)上,它的操作如下(有关术语,请参阅JLS 12.6.1):

  • GC 检测到无法访问的对象:

    • 如果对象有终结器方法,则将其添加到终结器队列中。
      该对象是finalizable

    • 如果该对象可以从一个可终结的对象中访问,则离开它。
      该对象是finalizer-reachable

    • 否则现在回收内存。
      对象无法访问

  • 后台终结器线程处理排队的可终结对象:

    • 调用finalize()方法。
      当方法返回时,对象是finalized
  • 由于 GC 已经完成,最终对象正在“休息”直到下一个 GC 周期。

  • 在下一个 GC 循环中,带有 finalizer 方法且标记为finalized的对象被视为不可达,并且内存将被回收(假设 finalizer 方法没有使对象再次可访问)。

请注意,当一个对象是finalizable时,可能会发生许多 GC 周期,即,Finalizer 线程可能需要一段时间来处理该对象。


推荐阅读