JVM判断对象是否是存活的有两个算法:引用计数法、可达性分析算法
Hotspot虚拟机用的是可达性分析,以GC Roots为起点进行搜索,如果对象直接或间接与根对象相连,则代表存活,如果没有相连,则表示该对象已经死亡或者可以被回收。
但真正要宣告一个对象死亡,需要至少经历两次标记过程:
- 如果没有与GC Roots相连,则会被第一次标记
- 其次需要判断是否有必要对该对象执行finalize()方法
- 如果该对象没有重写finalize方法,或者finalize方法已经被调用过一次了,那该对象会被判断为不可触及对象,可以被回收了。
- 如果该对象重写了finalize方法,并且还没被调用过,那会被放置在一个名为F-Queue的队列中,稍后由一条由虚拟机创建的,低调度优先级的finalizer线程去执行他们的finalize方法,之后垃圾收集器会对F-Queue进行第二次标记,如果在标记之前与GC roots相连了,则会被移出F-Queue队列,此时该对象是存活的。因为finalizer线程优先级低,所以可能对象还未执行finalize方法,就被第二次标记了,也会被判定为不可触及的对象,被回收。
注意:每个对象finalize方法只会调用一次,如果第二次还被标记为回收,则直接判定为不可触及对象