不同的引用类型,主要体现的是对象的不同的可达性(reachable)状态和对垃圾收集的影响。
image
引用类型 | 被垃圾回收时间 | 用途 | 生存时间 |
---|---|---|---|
强引用 | 从来不会 | 对象的一般状态 | JVM 停止运行时终止 |
软引用 | 当内存不足时 | 对象缓存 | 内存不足时终止 |
弱引用 | 正常垃圾回收时 | 对象缓存 | 垃圾回收后终止 |
虚引用 | 正常垃圾回收时 | 跟踪对象的垃圾回收 | 垃圾回收后终止 |
强引用是使用最普遍的引用,一般声明如下:
Object strongReference = new Object();
如果要对强引用进行垃圾回收,需要设置强引用对象为 null ,或者让其超出对象的生命周期范围,则认为改对象不存在引用。
strongReference = null;
可以看下 ArrayList 是如何进行内存释放的
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
软引用可用来实现内存敏感的高速缓存。
使用如下:
// 强引用
String strongReference = new String("abc");
// 软引用
String str = new String("abc");
SoftReference<String> softReference = new SoftReference<String>(str);
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
ReferenceQueue refQueue = new ReferenceQueue();
SoftReference softRef = new SoftReference(obj, refQueue);
软引用垃圾回收
if(JVM内存不足) {
// 将软引用中的对象引用置为null
str = null;
// 通知垃圾回收器进行回收
System.gc();
}
代表软引用的类:java.lang.ref.SoftReference 代表弱引用的类:java.lang.ref.WeakReference 代表虚引用的类:java.lang.ref.PhantomReference 他们同时继承了:java.lang.ref.Reference
public static void soft() throws Exception {
Object obj = new Object();
SoftReference<Object> softRef = new SoftReference<Object>(obj);
System.out.println(softRef.get()); //有时候会返回Null
// java.lang.Object@f9f9d8 System.out.println(refQueue.poll());
// null
// 清除强引用,触发GC
obj = null;
//System.gc();
System.out.println(softRef.get());
//Thread.sleep(200);
//System.out.println(refQueue.poll());
}
弱引用和软引用的区别在于:弱引用拥有更短暂的生命周期,不管内存够不够,都会回收,都会回收它的内存。
Object obj = new Object();
WeakReference<Object> weakReference = new WeakReference<Object>(obj);
obj = null;
System.gc();
System.out.println(weakReference.get());// 有时候会返回Null
System.out.println(weakReference.isEnqueued());//判断是否有垃圾回收标记,表示即将回收的垃圾
// 虚引用
Object obj = new Object();
ReferenceQueue refQueue = new ReferenceQueue();
PhantomReference<Object> phantomReference = new PhantomReference<Object>(obj, refQueue);
System.out.println(phantomReference.get()); // 永远返回Null
System.out.println(phantomReference.isEnqueued()); //返回时否从队列中删除
对象可达性分析
Java中4种引用的级别和强度由高到低依次为:强引用 -> 软引用 -> 弱引用 -> 虚引用