【Java核心-基础】引用(强引用、软引用、弱引用、幻象引用)

 

Java中的变量类型分为两大类:原始数据类型 和 引用类型。

 

引用类型分类

Java 中的引用分为“强引用”、“软引用”、“弱引用”、“幻象引用”。

这些分类体现了Java对象不同的可达性状态(reachable),是垃圾收集器决定如何处理对象的考虑因素之一。

分这么多类型,主要应用场景就是缓存(软引用、弱引用)。图片就是典型的缓存对象。

 

强引用

强引用就是最常见的普通对象引用。在垃圾收集(GC)中,对于一个对象,只要还有一个强引用指向该对象,就表明该对象还活着,GC不会去回收它。

 

软引用 

SoftReference

软引用是比强引用弱化一些的引用。可以让对象免于被某些GC操作回收。只有当 JVM 认为内存不足时(确保在OutOfMemoryError之前),才会试图回收软引用指向的对象

软引用一般用于实现内存敏感的缓存。即,如果还有空闲内存,则暂时保留缓存;当内存不足时,可以被清理掉。这样既可以使用缓存,又不会因缓存数据过多而耗尽内存。

如,在内存实现对图片数据的缓存。

 

弱引用

WeakReference

弱引用机制仅仅是提供一种途径来访问处于弱引用状态的对象。它不能让对象免于被回收。也可以用该机制实现缓存。

 

幻象引用

PhantomReference

幻象引用也译作虚引用。该机制仅仅是确保对象被 finalize 后,再执行某些操作。

 

对象可达性状态转换

【Java核心-基础】引用(强引用、软引用、弱引用、幻象引用)

 

与引用队列(ReferenceQueue)结合使用

软引用、弱引用、幻象引用都可以和引用队列(ReferenceQueue)结合使用,以便实现一些自定义的功能。

可以在创建引用时指定ReferenceQueue,当此引用所指对象的可达性变成对应的等级时,此引用会被添加到指定的ReferenceQueue中。

“可达性等级改变”是指可以通过相应等级的引用访问对象,但无法通过更高等级的引用访问。

如,“弱引用可达”是指可通过弱引用访问对象,但该对象的软引用和强引用都无法访问它。

 

例,对一个幻象引用采用这种使用方法:

Java代码

 【Java核心-基础】引用(强引用、软引用、弱引用、幻象引用)

  1. Object obj = new Object();  

  2. ReferenceQueue<Object> refQueue = new ReferenceQueue<>();  

  3. PhantomReference<Object> pRef = new PhantomReference<>(obj, refQueue);  

  4. obj = null;  

  5. System.gc();  

  6. try {  

  7.   Reference<Object> ref = refQueue.remove(1000);  

  8.   if (null != ref) {  

  9.     // 执行自定义操作  

  10.   }  

  11. } catch (InterruptedException e) {  

  12.   // 处理异常  

  13. }