WeakReference简介
什么是引用
首先要把引用和对象区别开来,比如Car car = new Car();
这条语句新建了一个对象new Car()
,同时把car
这个引用指向了这个new Car()
对象。java在gc的时候, 如果发现没有任何引用指向某对象, 该对象就会被回收。比如:Car car = null;
。
弱引用
上述描写的是java中的强引用,本文还将介绍一种WeakReference
弱引用。当GC时,如果一个对象只有弱引用指向他时候,那个对象就会被回收。
代码:
package reference;
import invoke.Car;
import java.lang.ref.WeakReference;
public class WeakReferenceDemo {
public static void main(String[] args) {
WeakReference<Car> weakReference = new WeakReference<>(new Car());
System.out.println(weakReference.get());
System.gc();
System.out.println(weakReference.get());
}
}
输出结果:
invoke.Car@198e2867
null
可以看到在gc之后新建的new Car()
对象因为只有弱引用指向他而被回收了。因为实际java程序中GC时机的不确定性,所以WeakReference常用作为cache,适合一些耗内存且更迭快速的对象。
ReferenceQueue的使用
WeakReference还提供了一种构造函数:
public WeakReference(T referent, ReferenceQueue<? super T> q) {
super(referent, q);
}
可以再传入一个ReferenceQueue作为第二个参数。
所以我把之前的程序稍加修改了一番:
package reference;
import invoke.Car;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
public class WeakReferenceDemo {
public static void main(String[] args) {
ReferenceQueue<Car> referenceQueue = new ReferenceQueue<>();
WeakReference<Car> weakReference = new WeakReference<>(new Car(), referenceQueue);
System.out.println(weakReference.get());
System.gc();
System.out.println(weakReference.get());
}
}
这个ReferenceQueue的主要作用是存放那些已经被gc的reference。
通过debug时候的两张截图能清晰看到gc前后的变化:
![](https://img.haomeiwen.com/i13825041/a0da34cc77f9268c.png)
![](https://img.haomeiwen.com/i13825041/68403b7d9dd8c12c.png)
referenceQueue存入了被gc的对象的弱引用。
SoftReference和PhantomReference
java中共有4种引用,上文已经讲了2种(强引用和弱引用),还有SoftReference和PhantomReference。
SoftReference和WeakReference类似,但他回收对象的条件要再加一条,当内存不足够的时候。
PhantomReference的情况就比较复杂了PhantomReference必须要和ReferenceQueue联合使用,虚引用并不会影响对象的生命周期。
当GC一旦发现了虚引用对象,则会将PhantomReference对象插入ReferenceQueue队列,作为跟踪垃圾回收器收集对象这一活动的情况。
网友评论