Java中的4种引用类型
强引用
强引用是最传统的“引用”的定义,是指在程序代码之中普遍存在的引用赋值,即类似“Object obj = new Object()”这种引用关系。无论任何情况下,只要强引用关系还在,垃圾收集器就永远不会回收掉被引用的对象。
示例
1 | String[] arr = new String[]{"a", "b", "c"}; |
软引用
软引用是用来描述一些还有用,但非必须的对象。只要被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够内存,才会抛出内存溢出异常。在JDK1.2之后,提供了SoftReference类来实现软引用。
示例
1 | //示例1 |
弱引用
弱引用也是用来描述那些非必须对象,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生未知。当垃圾收集器开始工作,无论当前内存是否足够,都会回收掉纸杯弱引用关联的对象。在JDK1.2之后,提供了WeakReference类来实现弱引用。
示例
1 | //示例1 |
虚引用
虚引用也被称之为“幽灵引用”或者“幻影引用”,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象示例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。在JDK1.2之后提供了PhantomReference类来实现虚引用。
示例
1 | ReferenceQueue<String[]> referenceQueue = new ReferenceQueue<String[]>(); |
多引用类型的可达性判断
若一个对象的引用类型有多个, 那到底如何判断它的可达性呢? 其实规则如下: (“单弱多强” )
- 单条引用链的可达性以最弱的一个引用类型来决定;
- 多条引用链的可达性以最强的一个引用类型来决定;
上图中,对象 C 虽然被对象 B 软引用着,但是因为存在一条 R->A->C 的全是强引用类型的路径,所以对象 C 是强可达的。
上图中,对象 A、对象 C 以及对象 D 都是软可达的,虽然对象 C 是被对象 A 强引用着,但是对象 A 本身是软可达的,所以对象 C 也是软可达的。所以你看,一个对象即使被强引用着,也可能是软可达的,比如这里的对象 C;一个对象即使被软引用着,也可能是强可达的,比如强可达那个图里的对象 C。