JavaScript WeakMap 不断引用 gc'ed 对象

标签 javascript garbage-collection ecmascript-6 weakmap

我正在使用 JavaScript weakmaps,在 google chrome 开发者控制台中尝试这段代码后,使用 --js-flags="--expose-gc"运行,我不明白为什么 weakmap 一直引用 a.b如果 a 被 gc 了。

var a = {listener: function(){ console.log('A') }}
a.b = {listener: function(){ console.log('B') }}

var map = new WeakMap()

map.set(a.b, [])
map.set(a, [a.b.listener])

console.log(map) // has both a and a.b

gc()
console.log(map) // still have both a and a.b

a = undefined
gc()
console.log(map) // only have a.b: why does still have a reference to a.b? Should'nt be erased?

最佳答案

2020 年 2 月更新

当我现在运行这段代码时,它按预期工作。我认为打开控制台会导致在以前版本的 Chrome 中保留对象,但现在不会。重新分配持有对象引用的变量的值将导致该对象被垃圾回收(假设没有其他对象引用它)。


在您的示例代码中,您没有释放您的 a 变量。它是一个顶级 var,永远不会超出范围,也永远不会被显式取消引用,因此它保留在 WeakMap 中。一旦代码中不再引用 Wea​​kMap/WeakSet 就会释放对象。在您的示例中,如果您在 gc() 调用之一之后 console.log(a) ,您仍然希望 a 是活着,对吧?

下面是一个工作示例,展示了 WeakSet 的实际应用,以及它如何在所有引用都消失后删除一个条目:https://embed.plnkr.co/cDqi5lFDEbvmjl5S19Wr/

const wset = new WeakSet();

// top level static var, should show up in `console.log(wset)` after a run
let arr = [1];
wset.add(arr);

function test() {
  let obj = {a:1}; //stack var, should get GCed
  wset.add(obj);
}

test();

//if we wanted to get rid of `arr` in `wset`, we could explicitly de-reference it
//arr = null;

// when run with devtools console open, `wset` always holds onto `obj`
// when devtools are closed and then opened after, `wset` has the `arr` entry,
// but not the `obj` entry, as expected
console.log(wset);

请注意,打开 Chrome 开发工具会阻止某些对象被垃圾回收,这使得实际操作比预期的更困难:)

关于JavaScript WeakMap 不断引用 gc'ed 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38203446/

相关文章:

javascript - 屏幕中间的 FlatList 没有显示全部内容

javascript - 如何获取仅相对的 offsetParent()

javascript - 我想动态地将事件附加到链接。但是 onclick 附加不起作用

php - 用于处理 URL 的服务器端脚本或函数

c# - VS2015升级后的垃圾回收和Parallel.ForEach问题

javascript - ES6 如何从一个文件中导出所有项目

javascript - ReactJS - 使用 useRef 和将变量放在组件之外有什么区别?

c# - 可以强制对象在第 1 代或第 2 代而不是第 0 代中被垃圾回收吗?

java - 内存使用本地变量而不是内联 Java

javascript - 如何制作与 await 一起使用但也可以接受回调的函数?