四种引用本质是jvm提供的对象存活控制粒度,区别在于gc处理策略:强引用永不回收、软引用内存不足时回收、弱引用每次gc必回收、虚引用仅用于回收通知且get()恒返回null。

强引用、软引用、弱引用和虚引用,本质是 JVM 给开发者提供的四种“对象存活控制粒度”,核心区别不在语法,而在 GC(垃圾回收器)对它们的处理策略不同——也就是“什么时候收、收不收、能不能用”这三件事。
强引用:默认存在,GC 绝不碰它
Object obj = new Object(); 这就是强引用。只要 obj 这个变量还有效(没被设为 null、没出作用域),JVM 宁愿抛 OutOfMemoryError 也不会回收它。它是内存泄漏的头号推手,比如静态 Map 里长期存着不用的对象,就因为强引用锁死了生命周期。
- 回收时机:永不主动回收(OOM 也不放)
- get() 是否可用:始终可用
- 典型场景:普通业务对象、单例、配置类实例
软引用:内存告急时的“缓存守门员”
SoftReference
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 回收时机:仅当堆内存即将耗尽(GC 前检测到内存不足)
- get() 是否可用:回收前可取;回收后返回 null
- 典型场景:图片缓存、HTML 页面缓存等内存敏感型缓存
弱引用:GC 扫到就清,不留过夜
WeakReference
- 回收时机:下一次 GC 触发时必回收
- get() 是否可用:GC 前可用;GC 后立即为 null
- 典型场景:WeakHashMap 的 key、ThreadLocal 的 value(防内存泄漏)、临时上下文绑定
虚引用:不能取对象,只等“回收通知”
PhantomReference
- 回收时机:对象进入 F-Queue 等待清除时即视为可回收
- get() 是否可用:永远返回 null(设计如此)
- 典型场景:资源清理钩子(如关闭堆外内存、释放文件句柄)、监控对象生命周期
强度排序是固定的:强 > 软 > 弱 > 虚。选哪种,关键看你要不要“让 GC 有选择权”——强引用说“绝不放手”,软/弱引用说“看情况松手”,虚引用说“我连手都不伸,只负责敲钟”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










