使用可转移对象时 Web Worker 内存泄漏

Web worker memory leak when using transferables

提问人:Kajuna 提问时间:3/14/2023 最后编辑:midnight-codingKajuna 更新时间:6/2/2023 访问量:212

问:

我将画布图像作为位图发送给 Web 工作人员,后者将其转换为 blob 并将其发送回去。在 postMessage 可转移对象中包含 ImageBitmap 和返回的 ArrayBuffer 似乎是获得更好性能的最佳做法,但由于 Chromium 版本 M93 或 M92 这样做会导致巨大的内存泄漏。我反复这样做,但要等到工人完成。直到 ElectronJS 13 (Chrome 91) 都很好。

简而言之,主进程将画布转换为位图并将其发送给工作线程:

createImageBitmap(canvas).then(bitmap => {
    worker.postMessage(bitmap, [bitmap]);
});

辅助角色创建 blob 并将其发回:

worker.onmessage = function ({ data }) {
    ctx.transferFromImageBitmap(data);
    canvas.convertToBlob().then(blob => {
        blob.arrayBuffer().then(arrBuf => {
            worker.postMessage(arrBuf, [arrBuf]);
        });
    });
};

这是简化的。在这个小提琴中可以找到一个更完整的例子:https://jsfiddle.net/1eqkfngc/(在小提琴中,内存最终会下降,而在 Electron 上则不会)

删除可转移对象数组可以解决内存问题,但理论上的性能较差。

我应该做一些不同的事情,还是这是 Chrome 中的错误?我已经提交了错误报告。

google-chrome electron chromium web-worker worker

评论

0赞 Kaiido 3/14/2023
当你强制垃圾回收时,它不会下降吗?您的代码中没有任何内容应该在内存中保留任何内容,因此这确实是一个浏览器错误。
0赞 Kajuna 3/14/2023
你会如何强制垃圾回收?我尝试过 bitmap.close()、bitmap = null 等方法,但无济于事。
1赞 Kaiido 3/14/2023
在浏览器中,将通过 dev-tools > 内存 > 收集垃圾(垃圾箱图标)。但在 Electron 中,我不确定。
0赞 Kaiido 3/14/2023
事实上,您不需要在此处显式关闭 ImageBitmap,BitmapRendingContext 应该会处理它。
0赞 Kajuna 3/15/2023
@Kaiido,事实上,在强制垃圾回收时会清除一些内存。不过,与以前的 Chrome 版本相比,性能仍然不是很好。我相信我已经将其缩小到 Chrome 92.0.4501.0 和 92.0.4502.0 之间的更改。这是错误报告,以防它帮助任何人连接想法: bugs.chromium.org/p/chromium/issues/detail?id=1424257

答:

0赞 Kajuna 6/2/2023 #1

此问题已在 Chrome 版本 115.0.5780.0 和 Electron 版本 26 左右修复