发件人:
第https://www.baeldung.com/java-memory-management-interview-questions的第11季度
当某个对象符合使用GC的条件时,垃圾收集器必须在其上运行finalize();此方法保证只能运行一次,因此收集器将对象标记为已完成,并让它休息直到下一个周期。
我有几个问题要问:
P.S:我确实知道在Java 9中最终不推荐使用finalize()。这要归功于好心人决定这么做。
答案 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周期,即,终结器线程可能需要一段时间才能处理该对象。