JVM 中的四类引用:强、软、弱、虚

发布于:2025-02-10 ⋅ 阅读:(49) ⋅ 点赞:(0)

导言
在 Java 开发中,垃圾收集(GC)机制通过自动管理内存提升了开发效率。但你是否知道 JVM 通过四种引用类型(强、软、弱、虚)精细控制对象生命周期?

强引用(Strong Reference)

特征:默认引用类型,只要强引用存在,对象绝不会被 GC 回收。

public class StrongReferenceDemo {
    public static void main(String[] args) {
        Object obj = new Object(); // 强引用
        System.out.println("GC前: " + obj);
        
        obj = null; // 切断强引用
        System.gc(); // 建议JVM执行GC
        
        System.out.println("GC后: " + obj);
    }
}

输出

GC前: java.lang.Object@15db9742
GC后: null

解析:将 obj 置为 null 后,原对象失去强引用,GC 会回收其内存。

软引用(SoftReference) 

特征:内存不足时,GC 会回收软引用对象。适合实现缓存。

public class SoftReferenceDemo {
    public static void main(String[] args) {
        SoftReference<byte[]> softRef = new SoftReference<>(new byte[10 * 1024 * 1024]); // 10MB
        
        System.out.println("GC前: " + softRef.get());
        System.gc();
        System.out.println("内存充足GC后: " + softRef.get());
        
        // 分配更多内存,触发内存不足
        byte[] newAllocation = new byte[15 * 1024 * 1024]; 
        System.out.println("内存不足时: " + softRef.get());
    }
}

运行参数-Xmx20M 限制堆内存为 20MB

输出

GC前: [B@6d06d69c
内存充足GC后: [B@6d06d69c 
内存不足时: null

弱引用(WeakReference)

特征:无论内存是否充足,GC 时立即回收。

public class WeakReferenceDemo {
    public static void main(String[] args) {
        WeakReference<Object> weakRef = new WeakReference<>(new Object());
        
        System.out.println("GC前: " + weakRef.get());
        System.gc();
        System.out.println("GC后: " + weakRef.get());
    }
}

输出

GC前: java.lang.Object@7852e922
GC后: null

虚引用(PhantomReference)

特征:无法通过虚引用访问对象,必须配合 ReferenceQueue 使用,用于追踪对象回收。

public class PhantomReferenceDemo {
    public static void main(String[] args) throws InterruptedException {
        ReferenceQueue<Object> queue = new ReferenceQueue<>();
        PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), queue);
        
        System.out.println("PhantomRef.get(): " + phantomRef.get()); // 始终为null
        
        System.gc();
        Thread.sleep(500);
        
        Reference<?> ref = queue.poll();
        if (ref != null) {
            System.out.println("对象已被回收,通过队列通知");
        }
    }
}

输出

PhantomRef.get(): null
对象已被回收,通过队列通知

应用场景:管理堆外内存(如 NIO 的 DirectBuffer),确保资源释放。

四类引用对比总结

引用类型 回收时机 常见用途
强引用 永不回收(除非不可达) 普通对象创建
软引用 内存不足时 内存敏感缓存
弱引用 下次GC时 缓存、WeakHashMap
虚引用 对象回收后 资源清理跟踪


网站公告

今日签到

点亮在社区的每一天
去签到