软引用、弱引用和虚引用

本文深入探讨Java中的四种引用类型:强引用、软引用、弱引用和虚引用的特点及应用场景,并详细解析了它们如何与垃圾回收机制协同工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一般来说,我们创建一个一般的对象,如:
Cow cow = new Cow();
这就是变量cow就是强引用,是强可触及的,和所有局部变量一样,对垃圾收集器来说,这是一个根节点。
#垃圾收集器的根节点的引用和强引用的对象包含的引用都是强引用。

在java的源码中,有这么几个类

-java.lang.ref
 +SoftReference<T>.java
 +WeakReference<T>.java
 +PhantomReference<T>.java
 +ReferenceQueue<T>.java
 +Reference<T>.java

其中,软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference),
它们都继承父类Reference,都有泛型<T>,T即为它们封装的对象t,可以通过构造函数来传封装对象t;
ReferenceQueue是Reference的一个属性域,可通过构造函数来传这个域值,当垃圾收集器要回收封装对象T,会调用
父类Reference的clear(),这样可以切断封装对象跟引用对象的关系,然后调用ReferenceQueue.enqueue(Reference<? extends ? super T> r)方法添加Reference引用到队列中。
这样,通过父类Reference.isEnqueued()便可知道封装对象是否已经被垃圾收集器回收,
若想取得封装的对象T,可调用父类Reference.get()方法,如果封装对象还没被回收,则会返回非null,不过对于虚引用,get()方法总会返回null的,这点需要注意。

##软引用对象
Cow cow = new Cow("niuniu");
java.lang.ref.ReferenceQueue<Cow> queue = new ReferenceQueue<Cow>();
java.lang.ref.SoftReference<Cow> softReference = new SoftReference<Cow>(cow, queue);
cow = null;
queue = null;

//softReference.clear();
//==>>this.referent = null; this:means SoftReference Object
//softReference.enqueue();
//softReference.isEnqueued();

##弱引用对象
Cow cow2 = new Cow("niuniu2");
ReferenceQueue<Cow> queue2 = new ReferenceQueue<Cow>();
java.lang.ref.WeakReference<Cow> weakReference = new WeakReference<Cow>(cow2, queue2);
cow2 = null;
queue2 = null;

##虚引用对象
Cow cow3 = new Cow("niuniu3");
ReferenceQueue<Cow> queue3 = new ReferenceQueue<Cow>();
java.lang.ref.PhantomReference<Cow> phantomReference = new PhantomReference<Cow>(cow3, queue3);
cow3 = null;
queue3 = null;

软可触及的
对象不是强可触及的,即不是强引用的对象,但可以从根节点通过一个或多个(未被清除的)软引用对象触及的。垃圾收集器只有在内存不够时,即会在抛出OutOfMemeryError之前,回收软引用触及的封装对象;
弱可触及的
对象不是强可触及的也不是软可触及的,但可以从根节点通过一个或多个(未被清除的)弱引用对象触及的。垃圾收集器在扫描可回收的对象时,只要扫描到弱引用封装的对象,不管虚拟机的内存够不够用,都定会将该封装的对象回收;java对弱引用,还提供了WeakHashMap<K, V>来保存弱可触及的对象,其中WeakHashMap的Entry便是继承了WeakReference
private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {
        V value;
        int hash;
        Entry<K,V> next;

        /**
         * Creates new entry.
         */
        Entry(Object key, V value,
              ReferenceQueue<Object> queue,
              int hash, Entry<K,V> next) {
            super(key, queue);
            this.value = value;
            this.hash  = hash;
            this.next  = next;
        }
        //...
}

虚可触及的
对象既不是强可触及、软可触及的,也不是弱可触及的,但可以从根节点通过一个或多个(未被清除的)虚引用对象触及的,它和软引用、弱引用区别:它必须有引用队列联合使用,也即是说构造函数必须传ReferenceQueu引用队列。虚引用,在任何时候都可以回收虚引用的封装对象,它跟软引用、弱引用不同,在任何时候,get()方法都会返回null,不过,垃圾收集器会先PhantomReference对象添加到ReferenceQueue队列中,然后再把回收虚可触及的对象,这点也是跟软、弱引用不同的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值