一. 四种引用类型
1. 强引用
对应类: FinalReference。
强引用比较普遍,例如:Object obj = new Object();这里的obj就是强引用,如果一个对象具有强引用,则垃圾回收器始终不会回收此对象。当内存不足时,JVM会抛出OOM异常使程序异常终止。
2. 软引用
对应类: SoftReference。如果一个对象只有软引用,则在内存充足的情况下是不会回收此对象的,但是,在内部不足时就会回收此对象。
public static void main(String[] args) {
Object obj = new Object();
SoftReference softRef = new SoftReference(obj);
obj = null; // 清除强引用
System.out.println(softRef.get() != null); // true
System.gc();
System.out.println(softRef.get() != null); // true
}
3. 弱引用
对应类: WeakReference。GC 发现一个对象只有弱引用,就会回收此弱引用对象。
public static void main(String[] args) {
Object obj = new Object();
WeakReference weakRef = new WeakReference(obj);
System.out.println(weakRef.get() != null); // true
obj = null; // 清除强引用
System.gc();
System.out.println(weakRef.get() != null); // false
}
4. 虚引用
对应类: PhantomReference 。虚引用并不会影响对象的生命周期,也无法通过虚引用获取对象。虚引用的作用为:跟踪垃圾回收器收集对象这一活动的情况。
public static void main(String[] args) {
ReferenceQueue<Object> rq = new ReferenceQueue<Object>();
Object obj = new Object();
PhantomReference phaRef = new PhantomReference(obj, rq);
obj = null; // // 清除强引用
System.out.println(phaRef.get() != null); // false
System.gc();
System.out.println(phaRef.get() != null); // false
}
二. 引用队列
引用队列(ReferenceQueue),在检测到适当的可到达性更改后,垃圾回收器将已注册的引用对象添加到队列中。
public static void main(String[] args) {
ReferenceQueue<Object> rq = new ReferenceQueue<Object>();
Object obj = new Object();
WeakReference weakRef = new WeakReference(obj, rq);
System.out.println(weakRef.get() != null); // true
obj = null; // 清除强引用
System.gc();
System.out.println(weakRef.get() != null); // false
// 对象被回收,引用对象添加到队列中
Reference<Object> r = (Reference<Object>) rq.poll();
System.out.println(r != null); // true
}
}
这个也是LeakCanary内存泄漏监测实现基础原理。如果内存发生泄漏,gc后ReferenceQueue中就找不到原来的引用对象。
三. 使用场景
- LeakCanary内存泄漏检测
网友评论