WeakRef 和垃圾回收未按预期工作

问题描述 投票:0回答:1

在我的项目中,我发现自己需要使用 WeakRefs 和 FinalizationRegistry,但我无法完全使其工作,所以我创建了一个简单的示例,但它也不起作用。你能帮我弄清楚为什么这个简单的例子不起作用:

示例代码:

    let ref = new WeakRef({});

    console.log("log", ref, ref.deref());

    global.gc();

    new Promise((res)=>{
        setTimeout(()=>{res()}, 100_000)
    }).then(()=>{
        console.log("log2", ref, ref.deref());
    })

    global.gc();

    console.log("log3", ref, ref.deref());

预期输出:

log WeakRef {} {}

log3 WeakRef {} undefined // maybe here still log3 WeakRef {} {}

log2 WeakRef {} undefined // here for sure!!!

实际输出:

log WeakRef {} {}

log3 WeakRef {} {}

log2 WeakRef {} {}

使用 global.gc() 不“强制”垃圾回收的替代方案也产生了上述结果。

我用来运行示例的命令:

node --expose-gc {filename}.js
如果是上面的代码或
node {filename}.js
在没有 global.gc() 的情况下运行测试时

我尝试过的节点版本: 17.9.1 20.10.0 21.7.3

javascript node.js garbage-collection weak-references
1个回答
0
投票
在同步执行观察到

WeakRef

 值的代码期间,不会发生垃圾收集。也就是说,当您构造 
new WeakRef(o)
 或从 
o = weakRef.deref()
 获取对象时,直到您的代码运行完成为止 
weakRef.deref()
 将始终返回 
o
。其间发生的垃圾收集周期(或使用 
global.gc()
 触发)无法收集该对象。

因此您需要稍微延迟一下通话,将其放入您的

setTimeout

let ref = new WeakRef({}); // even when a garbage collection happens (by chance) here console.log("log", ref, ref.deref()); // this will always return the object setTimeout(() => { global.gc(); // now it will be collected console.log("log2", ref, ref.deref()); }, 100);
    
© www.soinside.com 2019 - 2024. All rights reserved.