当一个对象脱离了GC Roots引用链,并不是马上就被回收的。会经历如下阶段:
1,该对象脱离GC Roots引用链,进行第一次标记。
2,判断该对象是否覆盖finalize()方法,如果没有,则真的就要被回收了。
如果该对象覆盖了覆盖finalize()方法,对象将会被放置在一个名为F-Queue的队列之中,并在稍后由一条由虚拟机自动建立的、低调度优先级的Finalizer线程去执行它们的finalize()方法。这里所说的“执行”是指虚拟机会触发这个方法开始运行,但并不承诺一定会等待它运行结束。这样做的原因是,如果某个对象的finalize()方法执行缓慢,或者更极端地发生了死循环,将很可能导致F-Queue队列中的其他对象永久处于等待,甚至导致整个内存回收子系统的崩溃。
一次性的免死金牌:
如果对象要在finalize()中成功拯救自己——只要重新与引用链上的任何一个对象建立关联即可,譬如把自己(this关键字)赋值给某个类变量或者对象的成员变量,那在第二次标记时它将被移出“即将回收”的集合。
注意 finalize()只会被执行一次,所以如果对象在第一次GC回收时,通过finalize()给自己续命了一次,但是很不幸,程序继续运行时,该对象再次脱离GC roots引用链了,在被标记为回收时,就不会再执行这个finalize()方法了,也就是死的翘翘的。