参考:深入理解Java虚拟机:JVM高级特性与最佳实践(第3版) 周志明 著
在可达性分析算法中判定为不可达的对象,也不是“非死不可”的,要真正宣告一个对象死亡,至少要 经历两次标记过程。
第一次标记
如果对象在进行可达性分析后发现没有与GC Roots
相连接的引用链,那它将会被第一次标记。
第二次标记
经过第一次标记后的对象,根据 此对象是否有必要执行finalize()方法 进行筛选,随后会由收集器对F-Queue
中的对象进行第二次小规模的标记。具体如下:
- 经过第一次标记后的对象,根据 此对象是否有必要执行finalize()方法 进行筛选。被判定为确实有必要执行
finalize()
方法的对象将会被放置在一个名为F-Queue
的队列之中。 - 假如对象没有覆盖
finalize()
方法,或者finalize()
方法已经被虚拟机调用过,那么虚拟机将这两种情况都视为“没有必要执行”。 - 稍后会由一条由虚拟机自动建立的、低调度优先级的
Finalizer
线程 去执行F-Queue
中对象的finalize()
方法。 finalize()
方法是对象逃脱死亡命运的最后一次机会,稍后收集器将对F-Queue
中的对象进行 第二次小规模的标记。如果对象在finalize()
中成功拯救自己——只要重新与引用链上的任何一个对象建立关联即可,那在第二次标记时它将被移出 “即将回收” 的集合;如果对象这时候还没有逃脱,那基本上它就真的要被回收了。- 这种自救的机会只有一次,因为对象的
finalize()
方法最多只会被系统调用一次。