JavaScript中WeakMap的值是否属弱可达,循环引用对象可否被GC回收
解答
核心结论
此时myProvider和factory都满足垃圾回收(GC)条件,会被正常回收。
WeakMap的引用规则
先明确ECMAScript规范中定义的WeakMap特性:
- WeakMap对键对象持有的是弱引用:如果键对象没有来自WeakMap之外的强引用,整个对应的键值对会被GC自动清理,不会阻止键对象被回收。
- WeakMap对值对象持有的是强引用:只有当对应的键对象处于强可达状态时,值的强引用才会生效,阻止值被回收;一旦键对象不可达,键值对整体被移除,值的强引用也随之消失。
场景拆解
强引用保留阶段(stronglyReachableProvider未置空时)
你的判断完全正确:
- 外部变量
stronglyReachableProvider是myProvider的强引用,因此myProvider处于强可达状态。 providerWeakMap中以myProvider为键,对应值是factory,此时键强可达,值的强引用生效,factory也被保留。providerFtnWeakMap中以factory为键,对应值是myProvider,进一步强化了两者的可达性,这个阶段两个对象都不会被回收,引用安全。
强引用移除阶段(stronglyReachableProvider = null后)
当你将唯一的外部强引用置空,且不存在其他外部强引用时:
myProvider不再有来自WeakMap之外的强引用,providerWeakMap中以myProvider为键的键值对会被GC标记为可清理,factory仅存的强引用随之消失。factory失去所有外部强引用后,providerFtnWeakMap中以factory为键的键值对也会被标记为可清理。- 两个对象形成的循环引用完全处于WeakMap内部,没有从GC根集(全局作用域、活动调用栈等)出发的强引用链,因此会被GC完整回收,不会产生内存泄漏。
内容的提问来源于stack exchange,提问作者DWoldrich
相关产品推荐
相关产品推荐

