这个简单的代码在一个数组中存储了100万个字符串(100个字符长度)。
function makestring(len) {
var s = '';
while (len--) s = s+'1';
return s;
}
var s = '';
var arr = [];
for (var i=0; i<1000000; i++) {
s = makestring(100);
arr.push(s);
if (i%1000 == 0) console.log(i+' - '+s);
}
当我运行它时,我收到此错误:
(...)
408000 - 1111111111111111111 (...)
409000 - 1111111111111111111 (...)
FATAL ERROR: JS Allocation failed - process out of memory
奇怪的是,100万* 100只是100兆字节。
但是如果我将s = makestring(100);
移到循环之外......
var s = makestring(100);
var arr = [];
for (var i=0; i<1000000; i++) {
arr.push(s);
if (i%1000 == 0) {
console.log(i+' - '+s);
}
}
执行时没有错误!
为什么呢?如何在节点中存储1百万个对象?
答案 0 :(得分:2)
当你将String生成移动到循环之外时,你基本上只需要创建一个String并将其推入数组一百万次。
然而,在数组内部,只使用指向原始String的指针,这比使用字符串保存百万次要少得多。
答案 1 :(得分:0)
您的第一个示例构建了1000000
个字符串。
在第二个示例中,您将使用相同的字符串对象并将其添加到数组1000000
次。 (它不是复制字符串;数组的每个条目都指向同一个对象)
V8做了很多事情来优化字符串的使用。例如,字符串连接比您想象的要便宜(在大多数情况下)。它不是建立一个全新的字符串,而是选择以链接列表方式连接它们。