引用不可达的对象什么时候才会被真正回收?

参考:深入理解Java虚拟机:JVM高级特性与最佳实践(第3版) 周志明 著

在可达性分析算法中判定为不可达的对象,也不是“非死不可”的,要真正宣告一个对象死亡,至少要 经历两次标记过程

第一次标记

如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记。

第二次标记

经过第一次标记后的对象,根据 此对象是否有必要执行finalize()方法 进行筛选,随后会由收集器对F-Queue中的对象进行第二次小规模的标记。具体如下:

  1. 经过第一次标记后的对象,根据 此对象是否有必要执行finalize()方法 进行筛选。被判定为确实有必要执行finalize()方法的对象将会被放置在一个名为F-Queue的队列之中。
  2. 假如对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,那么虚拟机将这两种情况都视为“没有必要执行”。
  3. 稍后会由一条由虚拟机自动建立的、低调度优先级的 Finalizer线程 去执行F-Queue中对象的finalize()方法。
  4. finalize()方法是对象逃脱死亡命运的最后一次机会,稍后收集器将对F-Queue中的对象进行 第二次小规模的标记。如果对象在finalize()中成功拯救自己——只要重新与引用链上的任何一个对象建立关联即可,那在第二次标记时它将被移出 “即将回收” 的集合;如果对象这时候还没有逃脱,那基本上它就真的要被回收了。
  5. 这种自救的机会只有一次,因为对象的finalize()方法最多只会被系统调用一次。
发布了178 篇原创文章 · 获赞 152 · 访问量 61万+

猜你喜欢

转载自blog.csdn.net/hbtj_1216/article/details/104140019