Java中的不同引用主要体现在 对象不同的可达性 和 对垃圾回收的影响。
首先了解一下对象的定向访问:Java程序是通过栈上的引用来操作堆上的具体对象。判断对象是否已死,可采用引用计数算法和可达性分析算法。其中,
1.引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,引用计数器+1;当引用失效时,计数器值就减1。任何时刻计数器为0的对象时不可能再被使用的。这个算法主要存在的问题就是,不能解决两个对象相互循环引用。
2.在主流的商用程序语言中,使用可达性分析算法来判定对象是否存活:通过GC Roots来判定。当一个对象到GC Roots没有任何引用链相连,即GC Roots到这个对象不可达,则说明此对象是不可用的,它们将会被判定为可回收对象。
【注】Java语言中,可作为GC Roots的对象:①虚拟机栈中引用的对象、②方法区中类静态属性引用的对象、③方法区中常量引用的对象、④本地方法栈中JNI引用的对象。
由上可知,判定对象是否存活是与对象的引用相关。JDK1.2以后,Java中引入强引用、软引用、弱引用和幻象应用来区分引用的强度,以上四种引用依次递减。
- 强引用:是强度最高的引用,在代码中普遍存在,类似Object obj = new Object;这类的引用,只要强引用还存在,垃圾回收器就不会回收被引用的对象。
- 软引用的强度稍弱,用来描述非必须的对象,对于软引用关联的对象,Java提供SoftReference来实现软引用,当内存不足时垃圾回收器才会对被软引用关联的对象进行第二次回收。
- 弱引用是比软引用更弱的引用,也是用来描述非必须的对象,Java提供WeakReference来实现弱引用,被弱引用关联的对象只能存活到下一次垃圾回收之前。
- 幻象引用又称“虚引用”,是最弱的一种引用关系,一个对象是否有虚引用的存在,完全不会对其生存时间造成影响,也无法通过虚引用来获取一个对象实例,只是在被虚引用关联的对象被回收时收到一个系统通知,Java提供PhantomReference来实现虚引用。