Java 垃圾收集期间何时调用finalize()?

Java 垃圾收集期间何时调用finalize()?,java,memory-management,garbage-collection,finalize,Java,Memory Management,Garbage Collection,Finalize,发件人: 第11题 当对象符合GC条件时,垃圾收集器必须对其运行finalize();此方法保证只运行一次,因此收集器会将对象标记为已完成,并在下一个周期之前对其进行休息。 我有几个问题要问: 那句话对吗 是在标记阶段,垃圾收集器调用finalize()方法吗 为什么它要休息到下一个周期 附言:我确实明白,在Java9中finalize()最终被弃用了。感谢善良的灵魂,他决定让这一切成为现实 是在标记阶段,垃圾收集器调用finalize()方法吗 依赖于实现,但通常不是。终结器在GC完成后由

发件人:

第11题

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

我有几个问题要问:

  • 那句话对吗
  • 是在标记阶段,垃圾收集器调用finalize()方法吗
  • 为什么它要休息到下一个周期
附言:我确实明白,在Java9中finalize()最终被弃用了。感谢善良的灵魂,他决定让这一切成为现实

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

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

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

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

在较高级别(简化),其操作如下(术语请参见):

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

    • 如果对象具有终结器方法,请将其添加到终结器队列。
      对象是可终结的

    • 如果可以从可终结对象访问该对象,请将其保留。
      对象是可访问终结器的

    • 否则,请立即回收内存。
      该对象无法访问

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

    • 调用
      finalize()
      方法。
      当方法返回时,对象被最终确定
  • 由于GC已经完成,最终确定的对象将“静止”到下一个GC周期

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


请注意,当对象可终结时,可能会发生许多GC循环,即终结器线程可能需要一段时间来处理该对象。

是的,这是正确的。我忘记了Java规范关于finalize有多具体,所以我不知道它是否确切说明了GC将调用哪个阶段
finalize()
,但“符合垃圾收集条件”是重要的一点。此时,对象可以
finalize()
@markspace规范()没有说明任何阶段。这是一个实现细节。实际上,实现不会将对象标记为“已完成”,而是将创建时具有非平凡的
finalize()
的对象标记为“未完成”,以便在可完成时取消标记。因此,垃圾收集器不需要区分没有终结器的不可访问对象和终结器已经运行的不可访问对象。请务必记住,当
finalize()
方法返回时,对象可能不是不可访问的(应该是,但该方法可能包含任意代码)。