即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正宣告一个对象的死亡,至少要经历两次标记过程:
如果对象在进行可达性分析后发现没有与GC Roots 相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖该方法,或该方法已被虚拟机调用过,虚拟机会将这两种情况都视为“没有必要执行”。
如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queue的队列之中,并在稍后由一个虚拟机自动建立的、低优先级的Finalizer线程去执行它。(执行是指虚拟机会触发它,但并不承诺会等待它运行结束。比如一个finalize()方法会执行特别久,或则死循环了,虚拟机就会提前结束该执行)。finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象要拯救自己,只要重新与引用链上的任何一个对象建立关联即可,那在死二次标记时,它将被移出“即将回收的集合”。如果对象这时候还没有逃脱,那基本上它就真的被回收了。