如何判断对象是否要回收
Java堆里存放着几乎所有的对象实例,垃圾收集器在回收对象前,第一件事就是确认这个对象是否还在被使用。
判断对象是否要回收的算法有两种,引用计数算法和可达性分析算法。
引用计数算法
引用计数算法 是给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加 1,当引用失效时,计数器值就减 1,任何时刻计数器为 0 的对象就是不可能再被使用的。
java虚拟机里面没有选用引用计数算法来管理内存,因为最主要的原因是它很难解决对象之间相互引用的问题。
如下代码:
public class ReferenceCountingGC {
ReferenceCountingGC referenceCountingGC;
public static void main(String []args){
ReferenceCountingGC rc1=new ReferenceCountingGC();
ReferenceCountingGC rc2=new ReferenceCountingGC();
rc1.referenceCountingGC=rc2;
rc2.referenceCountingGC=rc1;
}
}
以上两个对象相互引用,导致它们的引用计数都不为0,导致两个对象无法被回收。
可达性分析算法
Java中是通过可达性分析(Reachability Analysis)算法来判定对象是否存活的。
该算法是通过一系列的称为"GC Roots" 的对象 作为起始点,从GC Roots 开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到“GC Roots” 没有任何引用链相连时,则证明该对象是不可用的。
如上图,右边几个对象虽然有被引用,但是没有到达GC Root 所以会被判定为是可回收的对象。
可作为GC Root 的对象
1.虚拟机栈本地变量表中引用的对象。
2.方法区中类静态属性引用的对象。
3.方法区中常量引用的对象。
4.Native方法引用的对象。
参考
学习摘抄于深入理解Java虚拟机