jvm内存回收通过强、软、弱、虚四种引用强度分层管理对象存活:强引用阻止回收;软引用在内存溢出前回收;弱引用在每次gc时回收;虚引用仅用于回收通知,不阻止回收。

JVM 内存回收机制中,引用处理不是简单看“有没有引用”,而是依据引用强度分层判断对象存活状态。强引用默认阻止回收;软、弱、虚引用则在不同内存压力或GC时机下提供渐进式释放能力,是精细化内存管理的关键设计。
强引用:默认且最牢固的持有关系
只要对象被强引用直接或间接可达(即能从 GC Roots 沿引用链访问到),就不会被回收。即使发生 Full GC,强引用对象依然保留,除非显式置为 null 或超出作用域。
- 变量赋值、new 出的对象、静态字段指向的对象,默认都是强引用
- 它决定了对象的基本生命周期,也是 GC 可达性分析的主体依据
- 滥用强引用(如缓存长期持有大对象)易引发内存溢出
软引用:内存紧张时才释放的缓存保护伞
软引用对象在内存充足时不回收,仅当 JVM 即将抛出 OutOfMemoryError 前,会优先回收所有软引用指向的对象。
- 适合实现内存敏感型缓存(如图片缓存、查询结果缓存)
- 使用 SoftReference
包装对象,并建议配合引用队列(ReferenceQueue)监听回收事件 - 注意:JDK 不保证具体回收时机,仅保证“内存不足时尝试回收”
弱引用:每次 GC 都可能消失的临时关联
无论内存是否充足,只要发生 Minor GC 或 Full GC,仅被弱引用持有的对象就会被立即回收。
- 常用于构建非强制依赖的映射结构,比如 WeakHashMap 的 key
- 避免因缓存导致对象长期驻留堆中,防止内存泄漏
- 需配合引用队列及时清理已失效的弱引用本身,否则 WeakReference 实例会堆积
虚引用与终结器引用:回收通知与资源清理通道
虚引用(PhantomReference)不阻止回收,唯一作用是在对象被回收前入队,供程序执行清理逻辑(如释放堆外内存);终结器引用则关联 finalize() 方法,但已被标记为过时,不推荐使用。
- 虚引用必须与引用队列绑定,get() 方法始终返回 null
- 典型用途:配合 DirectByteBuffer 管理本地内存,或实现自定义资源释放钩子
- finalize() 执行不可靠、开销大、且 JDK 9 起已弃用,应改用 Cleaner 或 try-with-resources











