跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

强引用、软引用、弱引用及虚引用对对象回收影响

Java中四种引用类型定义对象存活语义:强引用永不回收;软引用在内存不足时回收,适合缓存;弱引用在每次GC时立即回收,用于临时映射;虚引用无法获取对象,仅配合引用队列通知回收,用于资源清理。

Java 中的四种引用类型——强引用、软引用、弱引用和虚引用——决定了垃圾回收器(GC)是否可以回收某个对象,以及在什么条件下回收。它们不是功能上的增强,而是对“对象存活与否”的不同语义定义。

强引用:最常用,不被 GC 回收平时写的Object obj = new Object()就是强引用。只要这个引用还存在(且没被置为 null),对象就永远不会被 GC 回收,哪怕内存不足抛出 OutOfMemoryError,也不会动它。

说明:强引用是默认引用类型,也是开发中最常使用的。它不参与 JVM 的引用队列机制,也不影响 GC 策略。

软引用:内存紧张时才回收,适合缓存用SoftReference

包装对象,例如:

SoftReference ref = new SoftReference<>(new byte[1024 * 1024]);JVM 在发生 GC 时,会先尝试保留软引用对象;只有在即将发生内存溢出(即内存真的不够用了)时,才会回收所有软引用指向的对象。

建议:

• 适合做内存敏感型缓存(如图片缓存、查询结果缓存)

• 不要依赖软引用一定长期存活,它只是“尽量留着”

• 可配合引用队列(ReferenceQueue)监听对象是否已被回收弱引用:GC 时立即回收,适合临时映射用WeakReference

包装,例如:

WeakReference ref = new WeakReference<>(new String("hello"));只要发生一次 GC(哪怕是 Minor GC),该对象就会被回收,不管当前堆内存是否充足。

常见用途:

• ThreadLocal 中的 key 使用弱引用,防止内存泄漏• WeakHashMap 的 key 是弱引用,避免 key 对象无法释放导致 map 持有其引用• 构建非强制生命周期依赖的映射关系(如监听器注册表)

虚引用:唯一不能获取对象实例的引用,仅用于回收通知用PhantomReference包装,必须配合ReferenceQueue使用。它不能通过 get() 获取对象(始终返回 null),唯一作用是:当对象被 GC 回收后,JVM 会把该虚引用加入关联的引用队列,从而让程序感知“对象已死”。

关键点:

• 虚引用不会阻止对象被回收• 必须与 ReferenceQueue 配合才能起作用• 常用于实现更精细的资源清理逻辑(如堆外内存释放、文件句柄关闭),替代或补充 finalize() 方法(后者已被弃用)

相关文章