WeakMap 通过弱引用键对象,使 GC 能在键无外部强引用时自动回收键及对应条目,避免内存泄漏;键只能是对象、不可遍历、不管理 value 引用,适用于附属元数据场景。

WeakMap 通过只接受对象作为键、且对键对象保持弱引用,让垃圾回收器能在对象不再被其他地方引用时自动回收它,从而避免因 Map 中长期持有对象引用导致的内存泄漏。
WeakMap 的键是“弱引用”的真实含义
WeakMap 的键对象不会阻止垃圾回收。只要该对象在 WeakMap 外部没有任何强引用(比如变量、属性、闭包捕获等),即使它仍是 WeakMap 的键,也会被 GC 回收。此时 WeakMap 内部对应条目自动消失——这个过程不触发任何回调,也不可枚举,是静默发生的。
对比普通 Map:如果用对象作键存进 Map,而该对象本该被释放,却因 Map 里还存着它而无法回收,就构成内存泄漏。
典型泄漏场景:DOM 元素绑定私有数据
为 DOM 元素附加状态(如是否已初始化、临时配置)时,若用 Map 存储,容易忘记清理:
- 用 Map:元素被移除 DOM 后,若未手动从 Map 删除对应项,该元素仍被 Map 强引用,无法回收
- 用 WeakMap:元素脱离 DOM 且无其他引用后,GC 自动回收元素,WeakMap 中的条目也随之消失,无需手动清理
示例:
const btn = document.getElementById('myBtn');
elementData.set(btn, { initialized: true, retryCount: 0 });
// btn 被 remove() 或页面卸载后,只要没其他引用,btn 和它的数据都会被回收
WeakMap 的关键限制与使用边界
它的设计决定了它只适合特定用途,不能替代 Map:
- 键只能是对象(不能是字符串、数字、symbol),因为只有对象才能被弱引用
- 不支持遍历(没有 keys()、values()、entries()),也无法获取 size,这是为避免暴露内部引用状态
- 不能防止值(value)被回收——value 是强引用,需自行管理 value 中的对象引用
- 仅适用于“附属元数据”场景:数据生命周期天然依附于某个对象实例
常见误用:以为 WeakMap 能“自动清理所有关联资源”
WeakMap 只解耦键的引用,不处理 value 中的副作用。例如:
- value 是一个定时器 ID,WeakMap 不会自动 clearTimeout
- value 包含事件监听函数,WeakMap 不会自动 removeEventListener
- value 是另一个大对象图,它本身仍可能造成泄漏(需确保该对象图也不强引用键)
真正安全的做法是:把 WeakMap 当作“免清理的私有存储”,业务逻辑中仍需在明确时机(如元素销毁前)主动清理副作用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











