java虚拟机的垃圾回收器怎么判断对象“已死”
前言
垃圾回收器在进行垃圾回收之前,要做的第一件事情就是判断哪些对象还“活着”,那些对象已经“死去”(即不可能再被任何途经他使用的对象)。
判断对象是否存活,有两种比较流行的算法:
- 引用计数算法
- 可达性分析算法
引用计数算法
算法描述
给对象添加一个引用计数器,每当有一个地方引用它的时候,计数器的值就增加一;当引用失效的时候,计数器的值就减一;任何时刻计数器的值为0的就是不可能再被引用的。
算法特点
引用计数算法,实现简单,效率也比较高,在大多数情况下是一个比较好的算法。但是至少主流的java虚拟机里面没有选择使用引用计数算法来管理内存的,其中最主要的原因是很难解决对象之间的循环引用的问题。
简单的例子:
1 | /** |
上面的例子中,两个对象已经不能被访问了,但是他们之间相互引用者对方,导致他们的引用计数不为0,于是引用计数算法无法通知GC回收器回收他们。
可达性分析算法
算法描述
这个算法的基本思想就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连接的时候,则证明对象是不可用的。
采用可达性分析算法,对象的三种状态:
- 可达状态 存在着道GC Root的引用链
- 可恢复状态 不存在到达GC Root的引用链,但是finalize方法还未触发,还有可能变成可达状态
- 不可达状态 不存在到GC Root的引用链,同时finalize方法已经执行过了
java语言中可作为GC Roots的对象包括下面几种:
- 虚拟机栈(栈帧中的本地变量表中)引用的对象;
- 方法区中类静态属性引用的对象;
- 方法区中常量引用的对象;
- 本地方法栈中JNI(及一般所说的Native方法)引用的对象;