7

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

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占用n的空间是长度为的空数组的空间1

我对此是否正确(特别是对于 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 上运行它。

4

2 回答 2

10

当您声明具有大小的数组时

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

于 2015-04-23T06:08:42.917 回答
6

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

于 2015-04-23T06:18:12.017 回答