jvm-如何判断对象已死?可达性分析

59 阅读2分钟

示意图

先来看示意图


image.png

root就是变量,非堆对象。

非堆对象包含什么?很显然,就是线程栈的方法的局部变量和方法区的类静态变量。

所以,root就是线程栈的方法的局部变量和方法区的类静态变量。

如何判断对象已死?

可达性分析的作用,就是判断对象是否已死。

核心就是上面的示意图,但是光看图,根本都不知道什么意思。如果只是用文字解释,其实也不知道是什么意思。

所以,必须要结合代码理解,否则说了半天,都是废话。

那上面的示意图到底是啥意思呢?

核心是gc root。这个只是一个名字而已,看这个名字,其实也不知道是啥意思。

那root到底是啥呢?其实就是一个变量。比如方法里的局部变量。

看代码

publicclass Test {
    public static void main(String[] args) {
	Test a = new Test(); //变量a就是root
	a = null; //a置为null之后,就没有变量指向刚刚创建的对象
    }
}

变量a就是root,指向new创建的对象(假设是对象1)。对象1被变量a指向,所以对象1是活的,不能被回收。但是,把a置为null之后,a就不再指向对象1,这个时候没有任何变量指向对象1,所以对象1就死了,可以被回收。

可达性分析也是基于引用

变量a指向对象1,其实就是变量a引用了对象1。所以,可以发现,所谓的可达性分析算法其实也是基于引用,这个和引用计数算法是一样的,都是基于引用。

总结

所以,引用计数算法是,有变量引用就加1。如果没有变量引用,计数就是0,表示对象已死。

可达性分析是,是否有变量引用。如果没有变量引用,表示对象已死。

这么描述,好像二者差不多,都是通过是否有变量引用,来判断对象是否已死。确实差不多,因为本来二者都是基于引用来判断。只不过实现的算法有区别,一个是计数,一个是可达性。

哪些变量可以作为root?

主要包括下面几种:

1、  线程栈的方法的局部变量

2、  方法区中的类静态变量

3、  方法区中的字符串字面量变量


具体的代码例子,可以参考:

blog.csdn.net/weixin_3800…

参考

www.xzgedu.com/p/t_pc/cour…