我写了一个生成数组的小程序,它运行很长时间(几乎永远;-):
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)?
还有一个问题:如果我运行
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上运行这个。
当您声明一个具有大小的数组时
Array(1024);
这样做是为了给1024个元素分配空间。它必须预先分配这个空间,因为这种声明数组的形式是一种优化声明
"我需要你保留1024个位置,这样你就不会在我把更多元素推到数组上时不断调整数组的大小"。
正如您可能知道的那样,用简单的[]
声明数组仍然可以将无限数量的元素推到它上面,但是,为了允许这种行为,数组正在幕后悄悄地调整大小(很可能是memcpy()
)。
编辑:
在第二个示例中获得更高迭代的原因是,您现在使用的是稀疏数组。使用稀疏阵列进行
var arr = []
arr[1000000] = 1;
这并不意味着您的数组现在在内存中使用1000000个条目。与密集阵列形成对比
var arr = Array(1000000);
它明确地告诉运行时保留一个数组,该数组可以在内存中存储1000000个条目。
相关StackOverflow问题:https://stackoverflow.com/a/1510842/276949
V8为一个看似空的数组中的每个元素使用4个字节。确定这一点的最佳方法是在Chrome中创建空数组,并使用探查器查看数组已经使用了多少额外的大小。看见https://developer.chrome.com/devtools/docs/heap-profiling有关如何做到这一点的详细信息。。。