问题描述
因此,WeakMap在键方面很弱...如果我有两个都将DOM元素存储为键且具有一些不同值的WeakMap,该怎么办?假设我们不能将它们组合在一起...
如果我们要从DOM中删除DOM元素,那意味着在某个时候,(键,值)对将从WeakMap中删除,对吧?
如果有两个WeakMap,那还能行吗?还是他们阻止对方删除它?
解决方法
如果两个WeakMap都与 key 拥有相同的元素,那么可以,一旦将元素从DOM中删除,垃圾收集器将可以自由地将其从两个WeakMap中删除。
唯一的问题是WeakMaps是否以某种方式持有对该元素的循环引用:否,如Bergi所说,不同WeakMaps中的循环引用会很好地收集垃圾,请参见https://jsfiddle.net/qzj5mxgL/一个例子。我必须将该代码作为SE的示例,以便我可以编辑答案,所以:
const delay = ms => new Promise(res => setTimeout(res,ms));
Promise.resolve()
.then(async () => {
const map1 = new WeakMap();
const map2 = new WeakMap();
console.log('not populated yet,check mem usage for jshell.net');
await delay(5000);
for (let i = 0; i < 1e5; i++) {
const elm1 = document.createElement('div');
const elm2 = document.createElement('div');
map1.set(elm1,elm2);
map1.set(elm2,elm1);
}
console.log('populated,check mem usage');
await delay(5000);
console.log('done,check mem usage');
return [map1,map2];
})
.then(async (maps) => {
await delay(1e9);
});
导致内存使用率增加,然后保持高位,然后减少-尽管有循环引用,它们的确获得了GCd。