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

Gol*_*den 5 javascript arrays sparse-array memory-consumption node.js

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

var results = [];
var i = 1;

while (true) {
  console.log(i++);
  results.push([]);
}
Run Code Online (Sandbox Code Playgroud)

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

var results = [];
var i = 1;

while (true) {
  console.log(i);
  results.push(new Array(i++));
}
Run Code Online (Sandbox Code Playgroud)

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

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
Abort trap: 6
Run Code Online (Sandbox Code Playgroud)

和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);
}
Run Code Online (Sandbox Code Playgroud)

然后我起床到1286175,然后再次崩溃:

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
Abort trap: 6
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*cny 6

声明具有大小的数组时

Array(1024);
Run Code Online (Sandbox Code Playgroud)

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

"我需要你保留1024个位置,这样你就不会随着我将更多元素推到它上而不断调整阵列大小".

正如您可能知道的那样,声明一个数组[]仍然允许您将无限数量的元素推送到它上,但是数组会memcpy()在后台静默调整大小(最有可能)以允许此行为.

编辑:

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

var arr = []
arr[1000000] = 1;
Run Code Online (Sandbox Code Playgroud)

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

var arr = Array(1000000);
Run Code Online (Sandbox Code Playgroud)

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

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


Ham*_*bba 5

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