Java四种引用类型本质是控制对象生命周期与垃圾回收的机制,强度排序为强引用>软引用>弱引用>虚引用,核心区别在于GC是否回收、何时回收、能否访问对象及是否需引用队列。

Java 中的四种引用类型,本质是控制对象生命周期与垃圾回收行为的机制。它们不是语法糖,而是 JVM 垃圾回收策略中明确区分的语义层级,强度由高到低排列:强引用 > 软引用 > 弱引用 > 虚引用。区别核心在于——GC 是否回收、何时回收、能否访问对象、是否需配合引用队列。
强引用:默认存在,不回收,直到显式断开
- 只要变量持有该对象(如
Object obj = new Object()),对象就不可被回收。 - 即使内存严重不足,JVM 宁愿抛出
OutOfMemoryError也不会回收强引用对象。 - 想释放?必须手动置为
null或让其自然超出作用域(如方法结束)。 - 常见于业务主逻辑对象、单例、静态成员等;也是内存泄漏最常见根源。
软引用:内存够就不动,快撑不住时才清理
- 对象只被软引用持有时,在内存充足时全程存活;仅当 JVM 预判即将 OOM(如老年代空间不足)时,才触发回收。
- 适合做缓存:比如图片、模板、计算结果——用户可能再用,但丢了也不致命。
- 可关联
ReferenceQueue:回收后,软引用实例会被入队,便于异步清理缓存条目。 - 注意:不是“每次 GC 都检查”,而是由 JVM 根据堆压力综合判断,具有延迟性和不确定性。
弱引用:GC 扫到就收,不讲条件
立即学习“Java免费学习笔记(深入)”;
- 只要一次 GC 发生(哪怕年轻代 Minor GC),且对象仅剩弱引用,就会立即回收。
- 生命周期极短,适合临时性、非关键缓存,例如
ThreadLocal的 value、某些 Map 的 key(如WeakHashMap的 key 就是弱引用,避免内存泄漏)。 - 同样支持
ReferenceQueue:回收后自动入队,可用于资源清理或状态监听。 - 无法保证对象存活到下一次调用,
get()返回 null 的风险极高,使用前务必判空。
虚引用:不能取对象,只用来“收尸通知”
-
PhantomReference.get()永远返回null,你无法通过它访问对象本身。 - 存在与否,完全不影响对象生命周期——对象只要没强/软/弱引用,随时可被回收。
- 唯一用途:配合
ReferenceQueue,在对象被回收前、内存释放前收到通知,用于执行 finalize 之外的清理动作(如关闭文件句柄、释放 off-heap 内存)。 - 必须传入
ReferenceQueue构造,否则无意义;且需配合ReferenceQueue.poll()主动轮询获取回收信号。
这四种引用不是替代关系,而是协同工具:强引用保核心,软引用缓热数据,弱引用防泄漏,虚引用做善后。用错类型,轻则缓存失效频繁,重则 OOM 或资源泄露。


















