【Java核心-基础】引用(强引用、软引用、弱引用、幻象引用)
Java中的变量类型分为两大类:原始数据类型 和 引用类型。
引用类型分类
Java 中的引用分为“强引用”、“软引用”、“弱引用”、“幻象引用”。
这些分类体现了Java对象不同的可达性状态(reachable),是垃圾收集器决定如何处理对象的考虑因素之一。
分这么多类型,主要应用场景就是缓存(软引用、弱引用)。图片就是典型的缓存对象。
强引用
强引用就是最常见的普通对象引用。在垃圾收集(GC)中,对于一个对象,只要还有一个强引用指向该对象,就表明该对象还活着,GC不会去回收它。
软引用
软引用是比强引用弱化一些的引用。可以让对象免于被某些GC操作回收。只有当 JVM 认为内存不足时(确保在OutOfMemoryError之前),才会试图回收软引用指向的对象
软引用一般用于实现内存敏感的缓存。即,如果还有空闲内存,则暂时保留缓存;当内存不足时,可以被清理掉。这样既可以使用缓存,又不会因缓存数据过多而耗尽内存。
如,在内存实现对图片数据的缓存。
弱引用
弱引用机制仅仅是提供一种途径来访问处于弱引用状态的对象。它不能让对象免于被回收。也可以用该机制实现缓存。
幻象引用
幻象引用也译作虚引用。该机制仅仅是确保对象被 finalize 后,再执行某些操作。
对象可达性状态转换
与引用队列(ReferenceQueue)结合使用
软引用、弱引用、幻象引用都可以和引用队列(ReferenceQueue)结合使用,以便实现一些自定义的功能。
可以在创建引用时指定ReferenceQueue,当此引用所指对象的可达性变成对应的等级时,此引用会被添加到指定的ReferenceQueue中。
“可达性等级改变”是指可以通过相应等级的引用访问对象,但无法通过更高等级的引用访问。
如,“弱引用可达”是指可通过弱引用访问对象,但该对象的软引用和强引用都无法访问它。
例,对一个幻象引用采用这种使用方法:
Java代码
-
Object obj = new Object();
-
ReferenceQueue<Object> refQueue = new ReferenceQueue<>();
-
PhantomReference<Object> pRef = new PhantomReference<>(obj, refQueue);
-
obj = null;
-
System.gc();
-
try {
-
Reference<Object> ref = refQueue.remove(1000);
-
if (null != ref) {
-
// 执行自定义操作
-
}
-
} catch (InterruptedException e) {
-
// 处理异常
-
}