如何判断对象是否死亡?(两种方法)
堆中几乎存放着所有的对象实例,对堆垃圾回收前的第一步就是要判断那些对象需要回收(也就是死亡,不能再被任何途径使用的对象)。
有两种方法来判断。
1、引用计数法
在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器就减1;任何时刻计数器为0的对象就是不可能再被使用的。
我们能看出来引用计数法原理简单,判定高效,但是在Java领域,至少是主流的Java虚拟机里面都没有用此方法来管理内存。
主要原因可能是:在两个对象出现循环引用的情况下,此时计数器永远不为0,导致无法对它进行回收。
public class Test {
public Object instance = null;
public static void main(String[] args) {
Test a = new Test();
Test b = new Test();
a.instance = b;
b.instance = a;
a = null;
b = null;
doSomething();
}
}
在上述代码中,a 与 b 引用的对象实例互相持有了对象的引用,因此当我们把对 a 对象与 b 对象的引用去除之后,由于两个对象还存在互相之间的引用,导致两个 Test 对象无法被回收。
2、可达性分析算法
这个算法的基本思想是通过一系列称为 “GC Roots” 的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的。
如下图,对象object 5,object 6,object 7,虽然互有关联,但是他们到GC Roots是不可达的,因此他们将会被判定为可回收的对象。