深入了解java虚拟机(JVM) 第五章 如何判断对象为垃圾对象
本章开始学习垃圾回收的过程,垃圾回收的过程首先就是要确定对象是否是垃圾对象,如果是垃圾对象,垃圾回收器才会进行回收。垃圾回收主要又两种算法:引用计数算法和可达性分析算法。
一、引用计数算法
引用计数算法就是在对象中添加了一个引用计数器,当有地方引用这个对象时,引用计数器的值就加1,当引用失效的时候,引用计数器的值就减1。当引用计数器的值为0时,jvm就开始回收这个对象。
简单的来说,在JVM中的栈中,如果栈帧中指向了一个对象,那么堆中的引用计数器的值就会加1,当栈帧这个指向null时,对象的引用计数器就减1。
这种方法虽然很简单、高效,但是JVM一般不会选择这个方法,因为这个方法会出现一个问题:当对象之间相互指向时,两个对象的引用计数器的值都会加1,而由于两个对象时相互指向,所以引用不会失效,这样JVM就无法回收。
二、可达性分析算法
针对引用计数算法的BUG,JVM采用了另一种方法:定义一个名为"GC Roots"的对象作为起始点,这个"GC Roots"可以有多个,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,即可以进行垃圾回收。
在上图中可以看到,如果时选用引用计数算法,object5, object6, object7之间互相引用,所以无法被回收。但是如果选用了可达性分析算法,虽然他们之间时相互引用,但是他们没有任何引用链和GC Roots连接,所以是可回收对象。
GC Roots对象一般包括有:1.虚拟机栈(栈帧中本地变量表)中引用的对象;2.方法区中类静态属性引用的对象;3.方法区中常量引用的对象;4.本地方法栈中JNI(Native方法)引用的对象。