无论是通过引用计数器判断的引用数量,还是通过可达性分析判断出的引用链是否可达,判定对象是否存活都跟引用有关。
在JDK1.2以前,引用被定义为当一个reference类型的数据代表的是另外一块内存的起始地址,该类型的数据被称之为引用,这种定义很纯粹,但是也很狭隘,一个对象在这种定义下只有被引用和没有被引用两种状态。对于描述一些“食之无味,弃之可惜”的对象就显得无能为力。我们希望能描述这类对象,当内存足够的时候,将它存放在内存中,当内存空间进行垃圾回收后显得还是内存紧张时,可以回收这部分对象,很多系统的缓存功能都符合这样的应用场景。因此在JDK1.2以后对引用进行重新的扩充,分为强引用、软引用、弱引用、虚引用4种,这四种引用的强度依次递减。以下分别进行介绍。
1、强引用
强引用是在代码中普遍存在的,类似于Object obj = new Object()
,这种new出来的对象引用属于强引用。只要强引用一直存在,垃圾收集器就永远不会回收被引用的对象。
2、软引用
软引用用来描述一些还有用但并非必须的对象,对于软引用关联着的对象,当内存溢出异常发生之前,通过垃圾回收进行二次回收。如果二次回收完成之后,系统内存依然不够,才会抛出内存溢出异常,在jdk1.2以后用SoftReference类来实现软引用。
3、弱引用
弱引用也是用来描述非必须对象的,但是它的强度相比于软引用来说更弱一些,它仅仅能生存到下一次垃圾回收之前。当垃圾收集时,无论内存是否足够,弱引用的对象都要被回收,在jdk1.2以后用WeakReference类来实现弱引用。
4、虚引用
虚引用是最弱的一种引用关系,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过一个虚引用来获取一个实例对象。为一个对象设置虚引用的唯一目的就是该对象在垃圾回收时受到一个系统通知,jdk1.2以后用PhantomReference实现虚引用。
SoftReference、WeakReference、PhantomReference都是Reference的直接子类。