可达性算法

在 Java 中,是通过可达性分析来判断对象是否存活的。该算法的基本思路是以一系列名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链Reference Chain,当一个对象到GC Roots没有任何引用链相连时(用图论的话来说就是GC Roots到这个对象不可达),则证明此对象时不可用的。

能成为GC Roots的对象包括下面几种:

栈帧中的局部变量表中的引用的对象。

方法区中的类静态属性引用的对象。

方法区中的常量引用的对象。

Native 方法引用的对象。

【为何不用引用计数法?】

引用计数算法:每当一个引用指向该对象,计数器的值就 +1,引用失效计数器的值就 -1。

引用计数算法很难解决循环引用的问题。循环引用举例:

public class ReferenceCountingGC { public Object instance = null; public static void testGC() { ReferenceCountingGC objA = new ReferenceCountingGC(); ReferenceCountingGC objB = new ReferenceCountingGC(); objA.instance = objB; objB.instance = objA; objA = null; objB = null; } }

上述代码中,到最后虽然 objA 和 objB 都为 null,但是两个对象的 instance 引用还都指向对方,导致这两个对象的引用计数器的值都为 1,无法回收。

【不可达对象的回收过程】

首先进行第一次标记,标记所有的不可达对象,在下次 GC 之前会执行对象的 finalize 方法。

没有重写 finalize 方法或 finalize 方法已经被虚拟机调用过的对象被直接清除。

重写 finalize 方法并且尚未调用的对象,将被放进一个队列中,稍后触发 finalize 方法。

finalize 方法是最后一个逃生门,执行过程中如果重新变的可达,就会在第二次标记时移出队列,第二次标记之后,队列中的对象都会被回收。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjffz.html