javascript - 如何在 Javascript 中观察 WeakMap 的垃圾收集?

标签 javascript weakmap

这是我对WeakMap的理解“对集合中对象的引用被弱保存。如果没有对存储在 WeakMap 中的对象的其他引用,它们可以被垃圾回收。”

为什么在删除引用后,WeakMap 中仍会出现以下键/值对? WeakMap 不应该为空吗?

let dog1 = {name: 'Snickers'};
let dog2 = {name: 'Sunny'};

var strong = new Map();
var weak = new WeakMap();


strong.set(dog1, 'Snickers is the best!');
strong.set(dog2, 'Sunny is the 2nd best!');
weak.set(dog1, 'Snickers is the best!');
weak.set(dog2, 'Sunny is the 2nd best!');

dog1 = null;
dog2 = null;

console.log(strong);
console.log(weak);

/*
Output
Map(2) {{…} => "Snickers is the best!", {…} => "Sunny is the 2nd best!"}
WeakMap {{…} => "Snickers is the best!", {…} => "Sunny is the 2nd best!"}
*/

setTimeout(function(){
console.log("1200ms later... waiting for garbarge collection");
console.log(strong);
console.log(weak);
}, 1200);

/*
Output
Map(2) {{…} => "Snickers is the best!", {…} => "Sunny is the 2nd best!"}
WeakMap {{…} => "Snickers is the best!", {…} => "Sunny is the 2nd best!"}
*/

最佳答案

在修复了@Amadan @Bergi @Geeganage 指出的错误后,以下代码在 Safari 和 Chrome 中提供了所需的输出,垃圾收集在几个新添加的超时之一之后运行。导致最终的 WeakMap 没有保留任何引用。

let dog1 = {name: 'Snickers'};
let dog2 = {name: 'Sunny'};

var strong = new Map();
var weak = new WeakMap();


strong.set(dog2, 'Sunny is the 2nd best!');
weak.set(dog1, 'Snickers is the best!');

dog1 = null;
dog2 = null;

console.log(strong);
console.log(weak);

/*
Output
[Log] Map {{name: "Sunny"} => "Sunny is the 2nd best!"} (1)
[Log] WeakMap {{name: "Snickers"} => "Snickers is the best!"} (1)
*/

setTimeout(function(){
console.log("1200ms later... waiting for garbarge collection");
console.log(strong);
console.log(weak);
}, 1200);

setTimeout(function(){
console.log("3200ms later... waiting for garbarge collection");
console.log(strong);
console.log(weak);
}, 3200);

setTimeout(function(){
console.log("6200ms later... waiting for garbarge collection");
console.log(strong);
console.log(weak);
}, 6200);

setTimeout(function(){
console.log("12200ms later... waiting for garbarge collection");
console.log(strong);
console.log(weak);
}, 12200);

/* 
Output (eventually)
[Log] Map {{name: "Sunny"} => "Sunny is the 2nd best!"} (1)
[Log] WeakMap {} (0)
*/

由于垃圾回收不能保证运行,如果你在滚动一个 JS 繁重的网站时将代码粘贴到控制台中,GC 可能实际上会在第一次超时后运行。

关于javascript - 如何在 Javascript 中观察 WeakMap 的垃圾收集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60087210/

相关文章:

javascript - 如何仅在生产模式下运行 'image-webpack-loader' webpack?

JavaScript/ES6 属性在构造函数中设置值时不使用 setter

javascript - Next.js:错误:React.Children.only 期望接收单个 React 元素子元素

javascript - 序列化事务批量更新,然后批量创建

javascript - 隐藏和重置功能无法正常工作

javascript - 如何获得悬停/鼠标悬停效果以保持选中状态?

javascript - 在 JavaScript 中使用元素作为哈希的键

javascript - 了解弱 map

javascript - 真正的弱引用事件发射器/调度器 : is it possible?

JavaScript 扩展类,同时使用 Wea​​kMap 作为私有(private)变量