在电子中通过 WebRTC 发送带有大量二进制数据的 ArrayBuffers 时发生内存泄漏

Memory leak when sending ArrayBuffers with large amounts of binary data over WebRTC in electron

我目前正在开发一个需要能够通过 WebRTC 数据通道发送文件的电子应用程序。我目前正在使用 PeerJS 作为一种抽象 WebRTC 并使开发更容易的方法。

我当前的实现使用发送方的 FileReader 来读取 32 KB 二进制块中的文件。然后将这些块放入 ArrayBuffer 中,然后将其与一些数据一起发送,以告诉另一方发送者发送的到底是什么。接收方然后将二进制数据写入文件。当接收方正在写入该数据时,发送方等待来自接收方的“文件继续”信号。接收方完成后,发送方会收到通知并发送下一个块。这一直持续到整个文件被发送。

在应用程序运行时发送的所有文件达到大约 500 兆字节之前,此方法一直有效。我认为这是由于内存泄漏导致的,我找不到根本原因。据我所知,我不会将对象保存在内存中,它们应该被 GC 清除。另一个相当不寻常的事情是只有文件的接收者会遇到这个问题。

我的应用程序中发生了很多事情,但我认为这是导致问题的部分。 (但请随时索取更多代码)。

这是应该写入 ArrayBuffer 的部分:

sm.writeChunk = function(arrayBuffer) { sm.receivedBytes += sm.receivedFileMeta.chunkSize; fs.appendFileSync(sm.downloadsFolder + path.sep + sm.receivedFileMeta.name + '.part' , new Buffer(arrayBuffer , 'binary'), 'binary', function (err) { if (err) { console.log(err); } }); sm.onAction({t:'file-progress', percent: sm.receivedBytes / sm.receivedFileMeta.size * 100}); sm.dataConnection.send({t: 'file-proceed'}); };

sm 是一个包含文件传输相关函数和变量的对象,因此称为“sm”。无处不在。

我试过将 ArrayBuffer 设置为未定义或 null,但似乎没有什么能让对象从内存中消失。甚至在文件传输完成后也没有。堆中的快照似乎支持这一点。同样删除 fs.appendFileSync 函数以使其不写入磁盘也没有区别。

我能做些什么来解决这个问题吗?或者这是与 PeerJS 相关的问题?非常感谢任何帮助或建议!

好吧,这似乎是一个 PeerJS 错误。看起来如果你想发送大于 16K 的数据包,PeerJS 会为你分块。内存问题在于分块。 PeerJS 以 16K 分块,而电子(实际上 chrome)一次可以发送 64K。这是为了保持跨浏览器兼容性,但由于我严格使用电子,所以我更改了 PeerJS 代码以不分块我的 32K 数据包。这解决了这个问题。