WeakHashMap的核心作用是让键可被垃圾回收器自动清理以避免内存泄漏;适用于监听器注册表、元数据缓存、对象身份快照等临时依赖场景,但不适用于业务缓存,且需注意键的弱可达性、禁用String字面量、遍历可能遇null键及线程不安全等问题。

WeakHashMap 的核心作用是让键(key)可以被垃圾回收器自动清理,从而避免内存泄漏——它不阻止键对象被回收,一旦键被回收,对应的键值对就自动从映射中消失。
什么时候该用 WeakHashMap?
适合管理“临时依赖关系”或“缓存型映射”,尤其是键对象生命周期不由你控制、但你想基于它关联一些辅助数据的场景:
- 监听器/回调的反向注册表:比如给某个 UI 组件动态添加监听器,又不想因为 Map 持有组件引用而阻止其被回收
- 元数据缓存:为第三方库返回的对象(如 Class、ClassLoader、Thread)附加自定义属性,但不希望因此延长其生命周期
- 对象身份快照映射:记录某时刻对象的状态,但不干预其存活时间
WeakHashMap 不是缓存解决方案
它不基于使用频率或过期时间淘汰条目,只响应键的可达性变化。所以不能替代 Guava Cache 或 Caffeine 做业务缓存:
- 键还在用,但长期没访问?WeakHashMap 不会删它
- 键已不可达,哪怕刚 put 进去一秒,下次 GC 后就可能消失
- 值(value)仍是强引用——如果 value 又反过来引用 key,会导致 key 无法回收(循环引用陷阱)
实际使用注意点
几个关键细节决定它是否真正生效:
立即学习“Java免费学习笔记(深入)”;
- 键必须是弱可达的唯一入口:确保没有其他强引用指向该 key 对象,否则 GC 不会回收它
- 别用 String 字面量作 key:字符串常量池中的字符串永远不会被回收,WeakHashMap 对它无效
- 遍历时可能遇到 null 键:调用
entrySet()或keySet()返回的集合是“弱一致”的,迭代中 key 可能被回收,对应 Entry 的 getKey() 返回 null - 线程不安全:和 HashMap 一样,多线程需外部同步,或包装为
Collections.synchronizedMap(new WeakHashMap())
基本上就这些。WeakHashMap 是个轻量但精准的工具——用对了省心,用错了等于没用。










