Node.js中稀疏数组的内存消耗

时间:2015-04-23 06:01:30

标签: javascript arrays node.js sparse-array memory-consumption

我编写了一个生成数组的小程序,运行时间很长(几乎永远; - )):

var results = [];
var i = 1;

while (true) {
  console.log(i++);
  results.push([]);
}

当我创建一个长度为i的稀疏数组而不是空数组时,程序崩溃得非常快:

var results = [];
var i = 1;

while (true) {
  console.log(i);
  results.push(new Array(i++));
}

实际上我起床i等于17424,然后我收到一条错误消息告诉我

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
Abort trap: 6

和Node.js将我带回控制台。由于唯一的区别是第二个产生比前一个更大的空数组,这意味着长度为n的空稀疏数组占空长数组空间的n1

我是否正确(特别是Node.js)?

还有一个问题:如果我跑

var results = [];
var i = 1;

while (true) {
  console.log(i);
  var temp = [];
  temp[i++] = i;
  results.push(temp);
}

然后我升到1286175,然后再次崩溃:

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
Abort trap: 6

为什么这与其他两个选项的行为不同?

PS:我正在使用Node.js 0.12.0在OS X上运行它。

2 个答案:

答案 0 :(得分:6)

声明大小为

的数组时
Array(1024);

您这样做是为1024个元素分配空间。它必须预先分配这个空间,因为这种声明数组的形式是一个优化陈述

“我需要您保留1024个位置,以便在我将更多元素添加到阵列上时不会不断调整阵列大小”。

正如您可能知道的那样,声明一个简单[]的数组仍允许您向其上推送无限数量的元素,但是数组在后台静默调整大小(很可能是memcpy())允许这种行为。

修改

您在第二个示例中获得更高迭代的原因是因为您现在使用的是稀疏数组。使用稀疏数组执行

var arr = []
arr[1000000] = 1;

并不意味着您的阵列现在在内存中使用1,000,000个条目。将其与密集阵列进行对比

var arr = Array(1000000);

明确告诉运行时保留一个可以在内存中存储1000000个条目的数组。

相关StackOverflow问题:https://stackoverflow.com/a/1510842/276949

答案 1 :(得分:4)

V8,Node中的JS引擎,在看似空的数组中为每个元素使用4个字节。找到这一点的最佳方法是在Chrome中创建空数组,并使用分析器查看数组已用尽的额外大小。有关如何执行此操作的详细信息,请参阅https://developer.chrome.com/devtools/docs/heap-profiling