Forcing garbage collection in Node to test WeakRef and FinalizationRegistry(强制节点中的垃圾回收以测试WeakRef和FinalizationRegistry)
问题描述
我正在玩WeakRef
and FinalizationRegistry
in V8,我无法验证以下代码在Node.js中是否可以正常工作。
我使用的是Node v15.3.0,运行方式如下:
node --expose-gc transient.js
:
我希望在控制台日志中看到一些finalizerCallback called!
条目。
如果我在基于Chromium浏览器(尝试Run code snippet
按钮)中运行它,当异步脚本仍在运行时,如果在DevTools(在Chrome v87中)的Performance部分中单击垃圾桶图标(收集垃圾),则可以获得输出。
它在Firefox v83中按预期工作,当脚本结束时,我看到所有终结器回调。
使用Node时,我希望在显式调用垃圾回收时自动看到它,但根本不会调用终结器回调。
代码本身是否有问题,或者是否有更可靠的方法在节点中强制GC?
数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">// by @noseratio
// see https://v8.dev/features/weak-references
class Transient {
constructor(eventTarget) {
const finalizerCallback = ({ eventTarget, eventListener }) => {
console.log('finalizerCallback called!');
eventTarget.removeEventListener('testEvent', eventListener);
}
const finalizer = new FinalizationRegistry(finalizerCallback);
const strongRefs = { finalizer };
const weakRef = new WeakRef(this);
const eventListener = () => {
console.log('eventListener called!');
strongRefs.finalizer = null;
weakRef.deref()?.test();
}
finalizer.register(this, { eventTarget, eventListener });
eventTarget.addEventListener('testEvent', eventListener, { once: true });
}
test() {
console.log("test called!");
}
}
async function main() {
const gc = globalThis?.global?.gc;
console.log(`garbage collector func: ${gc}`);
const eventTarget = new EventTarget();
for (let i = 10; i > 0; i--) {
void function () {
// these instances of Transient really must be getting GC'ed!
new Transient(eventTarget);
}();
await new Promise(r => setTimeout(() => r(gc?.(true)), 100));
}
console.log("finishing...")
gc?.(true);
await new Promise(r => setTimeout(r, 5000));
eventTarget.dispatchEvent(new Event("testEvent"));
console.log("done.")
}
main().catch(console.error);
已更新,如果我增加for
循环集成的数量,我最终会看到一些finalizerCallback
调用,但它们仍然是零星的。
推荐答案
我直接从@jasnell获取:
您可以尝试使用本机语法函数
%CollectGarbage
我试过了,它完全按照我想要的方式工作。在现实生活中,它是一个AbortController
对象链,更多上下文here。
启用%CollectGarbage
:
node --allow-natives-syntax Transient.js
要向静态代码分析器隐藏%
语法,我们可以使用eval
:
eval("%CollectGarbage('all')");
这篇关于强制节点中的垃圾回收以测试WeakRef和FinalizationRegistry的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:强制节点中的垃圾回收以测试WeakRef和FinalizationRegistry
- Flexslider 箭头未正确显示 2022-01-01
- 使用RSelum从网站(报纸档案)中抓取多个网页 2022-09-06
- 400或500级别的HTTP响应 2022-01-01
- CSS媒体查询(最大高度)不起作用,但为什么? 2022-01-01
- 失败的 Canvas 360 jquery 插件 2022-01-01
- 如何使用 JSON 格式的 jQuery AJAX 从 .cfm 页面输出查 2022-01-01
- Quasar 2+Apollo:错误:找不到ID为默认的Apollo客户端。如果您在组件设置之外,请使用ProvideApolloClient() 2022-01-01
- Css:将嵌套元素定位在父元素边界之外一点 2022-09-07
- Fetch API 如何获取响应体? 2022-01-01
- addEventListener 在 IE 11 中不起作用 2022-01-01