weakmap 在响应式库中以响应式对象为弱引用键映射依赖表,避免内存泄漏;其不可遍历、无 clear 等特性保障依赖私有性;作为三层嵌套结构(weakmap→map→set)入口,同时缓存代理对象并支持自动 gc。

WeakMap 在 Vue 或 React 类似响应式库中,核心作用是**以响应式对象为键,安全映射其依赖关系表**,既支持快速查缓存,又不阻碍垃圾回收。
为什么必须用 WeakMap 而不是 Map?
因为响应式对象可能随时被丢弃(比如组件卸载、数据被置为 null)。WeakMap 的键是弱引用——只要该对象在其他地方没了引用,即使它还在 WeakMap 里,也会被自动清理。Map 则会强持有键,导致对象无法被 GC,引发内存泄漏。
- WeakMap 键只能是对象,天然契合“每个响应式对象对应一份依赖表”的设计
- 没有 size、keys()、values() 等方法,不可遍历,符合“依赖关系应私有且不可外部干扰”的原则
- 不提供 clear(),避免误清全局依赖;靠 GC 自动解耦,更可靠
WeakMap 如何组织依赖结构?
它不是单独起作用,而是作为三层嵌套结构的入口层:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 外层:WeakMap → 原始对象(target)为键,值是一个 Map(叫 depsMap)
- 中层:Map → 属性名(key)为键,值是一个 Set(叫 effects)
- 内层:Set → 存储所有依赖该属性的 effect 函数(即副作用函数)
例如:targetMap.get(obj)?.get('count')?.has(effect1) 就能判断 effect1 是否依赖 obj.count。
WeakMap 还承担代理对象缓存职责
在 reactive() 实现中,WeakMap 同时用于避免重复代理同一个对象:
- 每次调用
reactive(obj),先查 WeakMap 是否已有obj → proxy映射 - 有则直接返回缓存的 proxy;没有则新建 Proxy 并存入 WeakMap
- 这样既保证同一对象只被代理一次,又不会因缓存导致对象无法释放
它不参与依赖清理,但保障清理有效
effect 自身维护一个 deps: Set 记录上次收集到的所有依赖 Set。重新执行前会调用 cleanup(),从每个 dep Set 中把自己删掉。WeakMap 不直接做这事,但它让整条链的起点可被回收——对象一消失,它对应的 depsMap 和里面所有 effects 都自然失效,不会有残留的“僵尸依赖”挂在内存里。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










