接着垃圾收集--判断对象是否存活(1) - 简书、垃圾收集--引用(2) - 简书上面这两篇论述,我们接着讨论对象是否存活的问题。
要真正宣告一个对象的死亡,至少要经历两次标记过程;所以在根搜索算法中不可到达的对象并不一定是“非死不可”的。
两次标记过程:
(1)对象在进行根搜索后发现没有与GC Roots相连接的引用链,它将会被第一次标记并进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。(当对象没有覆盖finalize()方法或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”。)
(2)筛选后被判定为有必要执行finalize()方法后,此对象会被放在一个名为F-Queue的队列里面,并稍后会由一条虚拟机自动建立的,低优先级的Finalizer线程去触发这个finalize()方法(但并不承诺会等待此方法运行结束,原因是防止导致内存系统崩溃)。
(3)在执行finalize()方法前,会对F-Queue里的对象进行第二次小规模的标记,若对象在第二次标记前成功的重新与引用链上的任意对象建立了关联(例如把自己赋值给某个变量或对象的成员变量),它就会在第二次标记时被移出“即将回收”集合。否则,将会被第二次标记(即意味着死亡)。
但在Java中关于对象死亡时的finalize()方法是不建议使用的,因为它的运行代价高,不确定性大。而且finalize()方法能做的所有工作,使用try-finally或其它方式可以做到更好更及时。