V8 / nodejs中的人工性能限制

时间:2017-05-04 06:01:09

标签: javascript node.js v8

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

然而,遇到麻烦的是,在尝试创建非常大的单个数组/地图/对象时。我最终得到如下错误消息:

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

而且:

RangeError: Invalid array length

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

要获取范围错误,请将其放入终端:node -e "new Array(5*1000*1000*1000)"

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

这些人为限制是众所周知的(12),显然是由于一些旧的垃圾收集器代码,V8团队害怕触摸知道将需要做很多工作才能修复(参见chromium bug report)。

问题:

对于那些了解V8和nodejs路线图的 :这些限制是否会被取消?我们可以期待多长时间等待?

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

1 个答案:

答案 0 :(得分:6)

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

我们知道对数组和字符串有大小限制是不幸的。但是,提高现有限制需要付出很多努力。我们想在某个时候这样做,但它现在没有优先权。 (这就是你引用的错误总结 - 我们并没有那么多害怕它,它只是非常重要的因为它不是而不是只是一个“阴险的人为限制”,我们没有时间给予其他优先考虑。)

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

说到JavaScript:ECMAScript规范定义new Array(n)只要RangeError就抛出n != ToUint32(n)5*1000*1000*1000不是uint32。所以这个特殊情况实际上是必需的行为;如果V8支持这样的阵列,那将违反规范。