在垃圾回收期间何时调用finalize()?

时间:2018-12-23 16:20:01

标签: java memory-management garbage-collection finalize

发件人:

https://www.baeldung.com/java-memory-management-interview-questions的第11季度

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

我有几个问题要问:

  • 那句话正确吗?
  • 是在标记阶段,垃圾收集器是否调用finalize()方法?
  • 为什么要休息直到下一个周期?

P.S:我确实知道在Java 9中最终不推荐使用finalize()。这要归功于好心人决定这么做。

1 个答案:

答案 0 :(得分:3)

  

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

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

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

  

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

在较高级别(简化)下,它的操作如下(有关术语,请参见JLS 12.6.1

  • GC检测到无法到达 的对象:

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

    • 如果可以从 finalizable 对象访问该对象,请保留它。
      该对象是 finalizer-reachable

    • 否则立即回收内存。
      该对象是不可达

  • Background Finalizer线程进程排队的 finalizable 对象:

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

  • 在下一个GC周期中,带有终结器方法且标记为 finalized 的对象被视为 unreachable ,并且将回收内存(假设finalizer方法没有再次使对象可达)。

请注意,当对象可完成时,可能会发生许多GC周期,即,终结器线程可能需要一段时间才能处理该对象。