0

この単純なコードは、配列に 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);
    }
}

これはエラーなしで実行されます!

なんで?ノードに100万個のオブジェクトを保存するにはどうすればよいですか?

4

2 に答える 2

2

String 生成をループの外に移動する瞬間は、基本的に 1 つの String を作成し、それを配列に 100 万回プッシュするだけです。

ただし、配列内では、元の文字列へのポインターのみが使用されます。これにより、文字列を 100 万回保存するよりもメモリ消費がはるかに少なくなります。

于 2013-01-28T07:45:40.210 に答える
0

最初の例は1000000文字列を構築します。

10000002 番目の例では、同じ文字列オブジェクトを取得し、それを配列timesに追加しています。(文字列をコピーしているわけではありません。配列の各エントリは同じオブジェクトを指しています)

V8 は、文字列の使用を最適化するために多くのことを行います。たとえば、文字列の連結は (ほとんどの場合) 思ったよりもコストがかかりません。まったく新しい文字列を作成するのではなく、通常、内部で連結リスト形式で接続することを選択します。

于 2013-01-28T07:46:41.957 に答える