Chrome / V8 如何处理 javascript 中的大对象?

How does Chrome / V8 deal with large objects in javascript?

我试图了解我在 Windows 10 上使用 Chrome / V8 看到的垃圾收集行为。场景是我有一个小程序接收 ~ 1MiB 的图像数据来自 websocket,频率约为 60Hz。我正在使用 Chrome 版本 81.0.4044.113(官方构建)(64 位)和 Windows 10 Pro 1903。

最小的接收代码如下所示:

var connection = new WebSocket('ws://127.0.0.1:31333');

connection.onmessage = message => {
    var dataCopy = new Uint8Array(message.data, 0);
};

Chrome 中的分析显示分配呈锯齿状上升,直到发生主要垃圾回收,并定期重复。分配都是 176 字节,与预期的 1 MiB 不匹配。

profile heap graph

我找到了 V8 GC 的精彩概述 here。如果我理解正确的话,当次要清除类型的 GC 可能会拾取这些分配时,我看到主要的 GC 事件似乎有点令人惊讶。此外,如上所述,分析时看到的分配没有预期的 1MiB 大小。

进一步的研究表明 SO question. Unfortunately the wiki mentioned has moved since the question was asked and I can't find any references to "large object space" at the new location 中描述了 "large object space"。我怀疑 1MiB 分配可能足够大,可以作为一个大对象,如果是这样,我想确认这些周围的实际行为是什么。

所以我的问题是:

最后我提交了一个V8的bug here 得到的答案是需要Major GC,因为消息对象分配在Blink的堆上,需要V8执行Major GC来协同回收内存. 176 字节的对象可能是指向堆上 ArrayBuffer 的指针。有一个正在进行的项目使 Blink 的 GC 分代,最终将改变这种行为。