V8 / nodejs中的人工性能限制

V8能够使用--max-old-space-size--max-old-space-size大量内存。 我经常使用节点来处理需要10GB +的任务,这非常棒 – 内存比较便宜,比从磁盘读取/写入要快得多。

然而,当我试图创build非常大的单个数组/地图/对象时,遇到了麻烦。 我结束了这样的错误消息:

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

和这个:

 RangeError: Invalid array length 

在这两种情况下,这并不是说我的电脑无法处理它,或者我的内存已经耗尽 – 这是因为在V8中隐藏了一些隐藏的人为限制。

为了得到范围错误,把它扔到你的terminal: node -e "new Array(5*1000*1000*1000)"

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

这些人为限制是众所周知的( 1,2 ),显然是由于V8团队害怕触摸的一些旧的垃圾收集器代码知道将需要大量的工作来解决(见铬缺陷报告 )。


题:

对于熟悉V8和nodejs路线图的人来说 :这些限制是否会被解除? 我们可以等待多久?

请注意,我理解模式像内存使用stream量较低,我知道nodejs和V8不是为“大数据”的东西 – 这个问题不是关于如何优化我的内存使用情况等。 只是对这些人为的限制对V8和nodejs路线图感到好奇。

V8开发者在这里。 总之,这不是路线图,对不起。

我们知道,数组和string的大小限制是不幸的。 但是,提高现有的限制将是一个很大的努力。 我们想在某个时候做,但现在没有优先权。 (这几乎是你所提到的错误总结 – 我们没有那么害怕 ,这只是不平凡的,因为它只是一个“阴险的人为限制”,我们没有时间它给了其他优先事项。)

这不仅一个努力的问题,也有技术上的考虑。 支持任意长度,尽pipe可能会使某些操作变慢。 我们认识到, 一些使用案例会从这种增加的灵活性中受益匪浅,但其他使用案例则可以从更简单,更快速的底层实施中获益。 find正确的平衡并不明显。 而且,我们仍然需要支持32位平台,其中指针大小对对象大小的限制较低,而且我们尽可能希望具有相同的行为,而不pipe底层硬件/操作系统如何。 这是首先有一个JavaScript虚拟机的一部分…

说到JavaScript:ECMAScript规范定义了当n != ToUint32(n)时, new Array(n)会引发RangeError5*1000*1000*1000不是uint32。 所以这个特例实际上是需要的行为; 如果V8支持这样的arrays,这将违反规范。