对象存活算法
在Java的垃圾收集器对堆进行回收之前,首先要判断,什么样的对象才是需要回收的对象,而什么样的对象是“存活”的对象。这就需要有一个判断的方法。
引用计数算法
有一种很简单粗暴的判断方法就是引用计数算法,即给对象中添加一个引用计数器,当出现一个地方引用该对象时,计数器的值就+1;当引用失效时,计数器的值就-1;当任意时刻计数器的值为0时,则判断该对象就不可能在被使用。这种算法实现很简单,且判断效率很高,当有一个问题,这种算法很难解决对象之间相互循环引用的问题,所以在Java虚拟机中并没有采用这种算法。
可达性分析算法
可达性分析算法的基本思想就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,所经过的路径称为“引用链(Reference Chain)”,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
通过这样的可达性分析,即使是两个相互循环引用的对象,也会被判断为不可到达GC Roots,从而判断为不可用对象。
可作为GC Roots的对象包括以下几种:
- 虚拟机栈(栈帧中的本地变量表)中的引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中JNI(Native方法)引用的对象
引用分类
强引用(Strong Reference)
强引用是指在程序代码之中普遍存在的,类似“Object obj = new Object()
” 这类的引用,只要强引用还在,垃圾收集器就永远不会回收掉被引用的对象。
软引用(Soft Reference)
软引用用于描述一些有用但不必要的对象,在系统将要发生内存溢出前,会把这类引用对象列入垃圾回收的范围,进行第二次回收。
弱引用(Weak Reference)
被弱引用关联的对象只能生存到下次垃圾收集发生之前。即当垃圾收集器开始工作时,一定会回收掉该类引用的对象。
虚引用(Phantom Reference)
为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。
本文参考自《深入理解Java虚拟机》第二版