WeakMap存在交叉引用时,是否会阻止JavaScript垃圾回收?
WeakMap交叉引用与垃圾回收分析
核心结论
WeakMap的弱引用机制决定了:只要没有外部强引用指向相关对象,哪怕对象之间、对象与WeakMap条目之间存在循环或交叉引用,垃圾回收器依然会回收这些对象,不会造成内存泄漏。
针对示例代码的分析
看你给出的代码:
let obj1 = {}, obj2 = {} obj1.ref = obj2 obj2.ref = obj1 const map1 = new WeakMap([[obj2, obj2]]) const map2 = new WeakMap([[obj1, obj1]]) obj1 = obj2 = null // obj1, obj2 garbage collected?
当执行obj1 = obj2 = null后,外部已经没有任何强引用指向这两个对象了。虽然obj1和obj2互相强引用,同时各自作为WeakMap的键和值,但WeakMap的键是弱引用——垃圾回收器不会把WeakMap对键的引用算作强可达性的依据,也不会因为值引用了键就改变这个规则。
所以这时候,垃圾回收器会判定obj1和obj2都是不可达的,会正常回收它们,map1和map2里对应的条目也会被自动清理。
关于双向WeakMap的补充
不管是单个WeakMap里的双向条目(比如键和值互相引用),还是多个WeakMap之间的交叉引用,只要所有涉及的对象都失去了外部强引用,垃圾回收器都会正确识别并回收这些对象。WeakMap的设计初衷就是为了在关联对象的同时,不干扰垃圾回收流程,不会因为内部的引用关系导致内存泄漏。
内容的提问来源于stack exchange,提问作者Miloš Šimek
相关产品推荐
相关产品推荐

