概述
java 中对象的回收是由jvm自动完成的,其工作区域是堆。一个通用的垃圾回收器应该需要考虑以下两个问题:
- 对象存活的判定,即什么样的对象需要被回收。
- 回收算法,即怎么回收。
本文主要讨论对象存活的判定,实现对象存活判定的方式主要有两种:引用计数法和可达性分析。
引用计数法
引用计数算法基本原理:
给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数值减1;任何时刻计数器为0的对象是不可能再被使用的。
引用计数计数算法的缺陷
class A {
public Object b;
}
class B{
public Object a;
}
public class Reference {
public static void main(String[] args) {
A a = new A();
B b = new B();
a.b = b;
b.a = a;
a = null;
b = null;
}
}
虽然a和b都被赋值为null,但是由于a和b存在循环引用,对象a和对象b的引用计数为1,这样a和b永远都不会被回收。
可达性分析
可达性分析算法基本原理:
通过一系列的称为”GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径成为引用链,当一个对象到GC Roots没有任何引用链相连(用图论的话来说就是从GC Roots到这个对象不可达)时,则证明此对象不可用。
java语言中的GC Roots:
1.在虚拟机栈中的引用对象。
2.在方法区中的类静态属性引用的对象。
3.在方法区中的常量引用的对象。
4.在本地方法栈中JNI(native方法)的引用的对象。