弱引用使对象在无强引用时立即可回收,不依赖内存压力或作用域结束;适用于监听器、上下文快照等临时对象,需配合referencequeue清理资源,且不可与强引用共存。

Java 垃圾回收配合弱引用管理临时对象,核心在于“让对象在无强引用时立即可回收”,不依赖内存压力,也不等待作用域结束。它不是用来延长存活时间,而是主动放弃持有权,把生命周期交给 GC 时机。
弱引用让对象“GC 一到就走”
只要一个对象只被弱引用持有(没有强引用或软引用),下一次任意 GC(Minor 或 Full)发生时,该对象就会被回收。这个过程完全自动,无需手动干预,也不看堆内存是否充足。
- 适合绑定临时、附属、非核心的对象,比如监听器、上下文快照、缓存元数据
- 不能用于需要稳定存在的业务实体——get() 返回随时可能为 null
- WeakReference 的 get() 方法必须每次调用前判空,不可假设对象还在
典型场景:避免监听器/回调导致的内存泄漏
注册监听器后忘记反注册,是强引用泄漏的高发区。用弱引用来持有监听器本身或其上下文,就能让主对象销毁后,监听器自然失效。
- 例如:UI 组件持有一个 WeakReference
,当 Activity 销毁且无其他强引用时,Listener 实例随之下线 - ThreadLocal 内部 key 就是 WeakReference,防止线程长期运行导致 ThreadLocal 实例无法卸载
- 不要把 WeakReference 当作“延迟释放”的手段——它不延迟,只放手
搭配 ReferenceQueue 及时清理关联资源
弱引用本身不通知你对象已消失。若需在回收后做清理(如关闭句柄、移除索引),要配合 ReferenceQueue 使用。
- 构造 WeakReference 时传入 ReferenceQueue,GC 回收后该引用会被加入队列
- 另起线程或在合适时机轮询 queue.poll(),拿到失效引用后执行 cleanup 逻辑
- 注意:queue 中的引用对象本身不持有原实例(get() 已返回 null),仅作标记用途
别和强引用混用,否则等于没用
WeakReference 生效的前提是“仅被弱引用持有”。一旦还有别的地方保留着强引用,哪怕只是日志打印时临时赋值、Map 里忘了 remove,对象就永远不会被回收。
- 检查静态集合、缓存容器、事件总线、单例类中是否意外长期持有了本该弱持有的对象
- WeakHashMap 是安全选择:它的 key 是弱引用,value 不影响 key 存活,Entry 在 key 被回收后自动清除
- 局部变量使用 WeakReference 后,记得及时让强引用(如 originalObj)脱离作用域或置 null
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











