深入理解JVM之引用计数法判断对象是否为垃圾

判断对象是否存活的算法一般是这样的:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器就加1,当引用失效时,计数器就减1;任何时刻计数器为0的对象就是不可能在被使用的。

客观的说,引用计数算法的实现简单,判定的效率很高,在大部分的情况下是一个不错的算法,也要一些著名的应用实例,比如微软公司的COM技术,使用ActionScript 3 的FlashPlayer,Python语言和在游戏脚本领域被广泛应用的Squirrel中都使用了引用计数算法进行内存管理。但是,至少主流的Java虚拟机里面没有选择引用计数算法来管理内存,其中主要的原因是它很难解决对象之间的相互循环引用的问题。


下面看一下示意图方便理解:

深入理解JVM之引用计数法判断对象是否为垃圾_第1张图片

左侧为堆,右边为栈。当堆中的对象之间有相互引用,但是栈中的应用并未指向相应对象的时候,使用引用计数器算法会存在弊端,上面也提及到了。就是对象实际上已经没有用了,但是由于对象之间存在相互的引用,对象的引用计数器不为0,所以该算法不会收集垃圾对象所占用的内存。

下面看一下代码验证当前JDK中的内存回收算法是不是引用计数器算法。在代码之前我们想要看到垃圾回收器的信息,要配置打印垃圾收集日志。这里有两个参数:

  • -verbose:gc : 打印垃圾回收的简单信息
  • -xx:+PrintGCDetails :详细信息
package jishuqisuanfa;

public class Main {

	private Object instance;
	
	public Main() {
		byte [] m = new byte[20*1024*1024]; 
	}
	public static void main(String[] args) {
		Main m1 = new Main();
		Main m2 = new Main();
		
		m1.instance = m2;
		m2.instance = m1;
		
		m1 = null;
		m2 = null;
		
		System.gc();
	}
}

结果:

深入理解JVM之引用计数法判断对象是否为垃圾_第2张图片

这里红框中显示对象的内存被回收了,显然,我们的JDK中并没有采用这种算法来收集垃圾对象所占的内存。

你可能感兴趣的:(Java,JVM)