2015-04-23 139 views
4

我已经写一个小程序,产生阵列,它运行相当长的(几乎永远;-)):代替空数组内存消耗

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

我是对的吗(具体到Node.js)?

一个问题:

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

为什么会出现这种行为比其他两个选项是不同的:如果我运行

var results = []; 
var i = 1; 

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

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

PS:我使用Node.js的0.12.0到在OS X上运行此

+0

我无法看到稀疏阵列。您可能想要移除该标签。 – monocell

+0

我已更新我的问题。 –

回答

6

在声明数组的大小

Array(1024); 

你这样做,它的分配空间1024个元素。它必须预先分配这个空间,因为这种声明阵列的形式是一个优化,它说明了一个优化,它说明了我需要你保留1024个位置,这样当我将更多的元素推到它上面时,你不会不断调整数组的大小”。你可能知道,声明一个简单的[]数组仍然允许你将无限数量的元素放到它上面,但是这个数组默默地在幕后调整大小(很可能是memcpy())以允许这种行为。

编辑:

你在第二个例子中得到更高的迭代究其原因,是因为你现在使用的是稀疏数组。用一个稀疏阵列做

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

并不意味着你的数组现在在内存中使用了1,000,000个条目。与此不同,密集排列

var arr = Array(1000000); 

其中明确告知运行时保留,可以在内存中存储的条目百万的数组。

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

+0

好的。感谢这:-) –

+0

我更新了我的问题。 –

+0

确定,更新回答 –

4

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

+0

我更新了我的问题。 –

+0

我的回答仍然正确吗? :) –