JavaScript(ES6) 将对象设置为 null 时的 WeakMap 垃圾回收

JavaScript(ES6) WeakMap garbage collection when set an object to null

我刚刚读到 WeakMaps 通过专门使用对象作为键来利用垃圾收集,并且将对象分配给 null 等同于删除它:

let planet1 = {name: 'Coruscant', city: 'Galactic City'};
let planet2 = {name: 'Tatooine', city: 'Mos Eisley'};
let planet3 = {name: 'Kashyyyk', city: 'Rwookrrorro'};

const lore = new WeakMap();
lore.set(planet1, true);
lore.set(planet2, true);
lore.set(planet3, true);
console.log(lore); // output: WeakMap {{…} => true, {…} => true, {…} => true}

然后我将对象设置为空:

planet1 = null;
console.log(lore); // output: WeakMap {{…} => true, {…} => true, {…} => true}

为什么输出一样?难道不应该删除它以便 gc 可以在应用程序中重用之前占用的内存吗?如有任何澄清,我将不胜感激。谢谢!

垃圾收集不会立即 运行。如果你想让你的例子工作,你需要强制你的浏览器运行垃圾收集。

运行 chrome 带有以下标志:google-chrome --js-flags="--expose-gc".

您现在可以通过调用全局 gc() 方法强制垃圾回收。

我试图在 2022 年弄清楚同样的事情,但如果 WeakMap 很小,浏览器似乎不会费心进行垃圾收集。

但是如果你这样做:

let weakmap = new WeakMap()

for (let i = 0; i < 2000; i++) {
    let john = {meow: i}

    weakmap.set(john, i)
    console.log(weakmap)
    john = null

    let div = document.createElement("div")
    div.innerText = i
    document.body.append(div)
    weakmap.set(div, i)
    div.remove()
}

let john2 = {} // Test to see if it garbage collects this (it shouldn't)

weakmap.set(john2, "random")

console.log(weakmap)

然后浏览器将在一定大小后进行垃圾回收:

如您所见,它的大小也从 4001 变为 101。看起来浏览器并没有费心收集其余部分的垃圾。