jvm垃圾回收-可达性分析算法之GC Roots理解

《深入理解JVM》原文:

  在主流的商用程序语言中(Java和C#),都是使用可达性分析算法判断对象是否存活的。这个算法的基本思路就是通过一系列名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,下图对象object5, object6, object7虽然有互相判断,但它们到GC Roots是不可达的,所以它们将会判定为是可回收对象。

 

 

 

 

一般来说,如下情况的对象可以作为GC Roots:

  1. 虚拟机栈(栈桢中的本地变量表)中的引用的对象
  2. 方法区中的类静态属性引用的对象
  3. 方法区中的常量引用的对象
  4. 本地方法栈中JNI(Native方法)的引用的对象

我的理解:

  可以看出,以上观点认为GC Roots是指对象,而我认为恰好相反,它指的应该是引用,不是堆中的对象。首先我们是能找虚拟机栈中的对象引用,也就是GC roots,通过它,我们能找到堆中被引用的对象,我们给他标记一次,然后顺着字段引用不断往下找,路径上的都标记一下。全部标记完成后,违背标记的就是不可达对象,进行回收。下面看一个简单的例子:

public static void main(String[] args) {
Object ref1 = new Object();
Object ref2 = new Object();
ref1 = ref2;
}

假设ref1指向的对象是堆中的对象instance1,ref2指向堆中的对象instance2,在第四行代码执行前后引用关系变化图如下:

 

 所以GC Root set指的是应该是引用的集合,可以分为以下几种:

  1. 虚拟机栈(栈桢中的本地变量表)中的引用
  2. 方法区中的类静态属性引用
  3. 方法区中的常量引用
  4. 本地方法栈中JNI(Native方法)的引用

最后,以上为我个人观点,如果有误,欢迎各位大佬批评指正。

posted @ 2019-12-04 20:24  一只有梦想的蜗牛  阅读(2653)  评论(2编辑  收藏  举报