V8 / nodejs 中的人为性能限制

Artificial performance limits in V8 / nodejs

V8 能够使用 --max-old-space-size 获得 运行 大量内存。我经常将节点用于需要 10GB 以上的任务,它很棒 - 内存便宜而且比 reading/writing from/to 磁盘快得多。

然而,我 运行 遇到麻烦的地方是在尝试创建非常大的个体时 arrays/maps/objects。我最终得到这样的错误消息:

FATAL ERROR: invalid table size Allocation failed - JavaScript heap out of memory

还有这个:

RangeError: Invalid array length

在这两种情况下,并不是我的计算机无法处理它,也不是我 运行 内存不足 - 这是因为 V8 中隐藏了一些阴险的人为限制。

要获得 运行ge 错误,请在您的终端中输入:node -e "new Array(5*1000*1000*1000)"

并得到无效的 table 大小错误:node -e "(new Array(200*1000*1000)).fill(1)"

这些人为限制是众所周知的 (1, 2), and are apparently due to some old garbage collector code that the V8 team is scared of touching knows will take a lot of work to fix (see chromium bug report)。


问题:

非常了解 V8 和 nodejs 路线图的人:这些限制会被取消吗?我们大概要等多久?

请注意,我了解流媒体等较低内存使用率的模式,并且我知道 nodejs 和 V8 不是为 "big data" 制作的 - 这个问题不是关于如何优化我的内存使用和像。只是对这些人为限制方面的 V8 和 nodejs 路线图感到好奇。

这里是 V8 开发人员。简而言之,它不在路线图上,抱歉。

我们知道数组和字符串的大小限制是不幸的。但是,提高现有限制将需要付出很多努力。我们想在某个时候这样做,但现在没有优先权。 (这几乎就是您提到的错误的总结——我们并没有那么 害怕 ,它只是非常重要,因为它 不是 只是一个 "insidious artificial limit",我们没有时间考虑其他优先事项。)

也不只是努力的问题,还有技术方面的考虑。支持任意长度虽然可能,但会使某些操作变慢。我们认识到 一些 用例会真正受益于这种增加的灵活性,但是 其他 个用例受益于更简单、更快的底层所带来的速度执行。找到正确的平衡并不明显。此外,我们仍然必须支持 32 位平台,其中指针大小对例如对象大小,我们尽可能希望有相同的行为,而不管底层 hardware/OS。这就是首先拥有 JavaScript VM 的部分意义...

谈到 JavaScript:ECMAScript 规范定义 new Array(n) 每当 n != ToUint32(n) 时抛出 RangeError5*1000*1000*1000 不是 uint32。所以这种特殊情况实际上是必需的行为;如果 V8 支持这样的数组,那将违反规范。