来自:
https://www.baeldung.com/java-memory-management-interview-questions的Q11
当一个对象有资格使用GC时,垃圾收集器必须在其上运行finalize();保证此方法只能运行一次,因此收集器将对象标记为已完成,并让其休息直到下一个周期。
我有几个问题要问:
那句话正确吗?
是在标记阶段,垃圾收集器是否调用finalize()方法?
为什么要在下一个周期之前休息一下?
P.S:我确实知道在Java 9中最终不推荐使用finalize()。这要归功于优秀的灵魂决定这么做。
最佳答案
是在标记阶段,垃圾收集器是否调用finalize()方法?
依赖于实现,但通常没有。 GC完成后,终结器由后台线程调用。
请记住,GC可能是世界停止的事件,并且应尽可能短。终结器方法可能很慢,因此不应在GC期间调用它们。
为什么要在下一个周期之前休息一下?
在较高级别(简化)下,它的操作如下(有关术语,请参见JLS 12.6.1):
GC检测不到的对象:
如果对象具有终结器方法,请将其添加到终结器队列。
该对象是可终结的。
如果可以从可终结对象访问该对象,请将其保留。
该对象是终结器可访问的。
否则,请立即回收内存。
该对象无法到达。
后台终结器线程进程排队的终结对象:
调用finalize()
方法。
方法返回时,对象完成。
由于GC已经完成,因此最终对象将“保留”直到下一个GC周期。
在下一个GC周期中,带有标记为finalized的finalizer方法的对象将被视为不可访问,并且将回收内存(假定finalizer方法无法使该对象再次可访问)。
请注意,在对象可终结时,可能会发生许多GC周期,即,终结器线程可能需要一段时间才能处理该对象。
关于java - 在垃圾回收期间何时调用finalize()?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53905181/