相信在我们Java程序猿中绝大多数的人都知道,Java垃圾回收器回收对象的条件就是在对象失去引用的情况下才会被垃圾回收器回收,但是谈论到计算对象是否被引用的算法以及引用对象的种类可能就会有一部分人不是了解的太具体。下面就简单介绍一下计算对象是否失去引用的算法以及强、软、弱、虚四种引用类型。
可达性分析算法
在主流的商用语言中(Java、c#等)都是用可达性分析算法来判定对象是否存活(也就是是否有引用指向这个对象)。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这个节点开始向下搜索,搜索走过的路径称为引用链,当一个对象到GC Roots没有引用链相连(就是从GC Roots不能到达这个对象)时,则证明此对象是不可用的(对象失去引用)。如图所示,对象object 5、object 6、object 7虽然互相有关联,但是他们到GC Roots是不可到达的,所以他们将会被判定为可以回收的对象。
在Java语言中,可作为GC Roots的对象包括以下几种:
1、虚拟机栈(栈帧中的本地变量表)中引用的对象。
2、方法区中类静态属性引用的变量。
3、方法区中常量引用的对象。
4、本地方法栈中JNI(Native方法)引用的对象。
Java中引用的分类
在jdk 1.2之后,Java堆引用的概念进行了扩充,将引用分为强引用、软引用、弱引用、虚引用四种,这四种引用强度依次减弱。
1、强引用:强引用就是在程序代码中普遍存在的,类似“Student student = new Student()”,这类的引用,只要引用还在,垃圾回收器就永远不会回收被引用的对象。
2、软引用:软引用是用来描述一些还有用但并非必须的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列入到回收范围之内进行二次回收。如果这次回收之后还没有足够的内存,才会抛出内存溢出异常。
3、弱引用:弱引用也是用来描述非必须对象的,但是它的强度要比软引用弱一些,被弱引用关联的对象只能生存到下次垃圾回收之前。当垃圾回收器工作时,不管内存是否足够都会回收掉被弱引用指向的对象。
4、虚引用:虚引用是最弱的一种引用关系。一个对象是否会被回收与其是否被虚引用所指向没有关系,虚引用并不能改变对象的生存时间,我们也无法通过虚引用获得对象的实例。为一个对象设置虚引用的唯一目的就是在回收这个对象的时候会得到一个系统通知。