JavaScript WeakMap继续引用gc'ed对象 [英] JavaScript WeakMap keep referencing gc'ed objects

查看:87
本文介绍了JavaScript WeakMap继续引用gc'ed对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JavaScript弱映射,在Google Chrome开发者控制台中尝试此代码并以--js-flags =-expose-gc"运行后,我不明白为什么弱映射会一直引用ab如果是gc'ed.

I am experiencing with JavaScript weakmaps, after trying this code in google chrome developer console, running with --js-flags="--expose-gc", I don't understand why the weakmap keep having a reference to a.b if a is gc'ed.

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?

推荐答案

UPDATE 2/2020

UPDATE 2/2020

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

When I run this code now, it works as expected. I think having the console open was causing objects to be held onto in previous versions of Chrome but not now. Reassigning the value of a variable that holds a reference to an object will cause that object to be garbage collected (assuming nothing else has a reference to it).

在示例代码中,您没有释放a变量.这是一个顶级var,永远不会超出范围,也不会被明确取消引用,因此它保留在WeakMap中.一旦代码中没有更多引用,WeakMap/WeakSet就会释放对象.在您的示例中,如果您在调用gc()之一后又console.log(a),您仍然希望a仍然有效,对吗?

In your example code, you're not releasing your a variable. It's a top level var that never goes out of scope and never gets explicitly de-referenced, so it stays in the WeakMap. WeakMap/WeakSet releases objects once there are no more references to it in your code. In your example, if you console.log(a) after one of your gc() calls, you'd still expect a to be alive, right?

因此,这是一个工作示例,展示了WeakSet的实际运行情况,以及一旦所有对它的引用都消失了将如何删除该条目:

So here's a working example showing WeakSet in action and how it'll delete an entry once all references to it are gone: 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开发工具会阻止某些对象被垃圾回收,这比实际预期的要困难得多:)

Note that having Chrome dev tools opened prevents some objects from getting garbage collected, which makes seeing this in action more difficult than expected :)

这篇关于JavaScript WeakMap继续引用gc'ed对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆