垃圾回收是JVM应用程序至关重要的一部分。那么JVM如何判断一个对象是否能被回收呢?JVM判断对象能否被回收的方法,主要经历过如下两种算法。

1、引用计数算法

    引用计数(Reference Counting Collector)算法是垃圾收集器中的早期策略,现在其实没有主流语言在使用了。

    在这种方法,堆中每个对象实例都有一个引用计数。当一个对象被创建,且被分配给一个变量时,该对象计数为1。当任何其它变量被赋值为这个对象的引用时,计数加1;而当对象实例的某个引用超过了生命周期或者被设置为新值,对象实例的引用计数器减1。任何引用计数器为0的对象实例可以被回收。当一个对象实例被回收时,它引用的任何对象实例的引用计数器减1。

    这种算法的优点:可以很快的执行,交织在程序运行中,不会长时间打断程序。

    缺点:无法检测循环引用。两个对象互相引用,它们的引用计数永远不为0。

2、可达性分析算法

    主流商用程序语言的主流实现都是通过可达性分析算法判断对象是否存活。

    可达性分析算法通过一系列GC Roots对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain)。当一个对象到GC Roots没有任何引用链相连,则此对象不可用,被判断为不可达的对象。

    Java语言中,可作为GC Roots的对象包括如下几种:

1)虚拟机栈(栈帧中的本地变量表)中引用的对象:虚拟机栈中存放的是以栈帧的形式存储的方法,因此“虚拟机栈中引用的对象”可以理解为待执行的方法中的局部变量所引用的对象;

2)方法区中类静态属性引用的对象:静态变量指的是static修饰的类的成员变量;

3)方法区中常量引用的对象:常量指的是final修饰的变量;

4)本地方法栈中JNI(即Native方法)引用的对象:本地方法指的是用其他语言实现的方法。

 

附:对垃圾回收的算法感兴趣请戳垃圾回收算法