2017-02-24 9 views
0

以下のコードでは、メモリが継続的に増加するとは思っていませんが、Chromeのデバッガによれば、それはそうです。なぜこのコードはメモリリークを引き起こしますか?

ループの途中で、前のタイムアウトが完了するのに十分な10ミリ秒を待ちます。それでも記憶は解放されていないようです。何故ですか?

while (true) { 
    let giantArray = Array(100000).fill().map(() => Math.random()); 
    await new Promise((resolve) => setTimeout(resolve, 10)); 
    setTimeout(() => { 
     giantArray[3] = 3; // If I don't reference giantArray, there is no leak 
    }, 1); 
} 
+0

実行時に正確に何が起こるのかを知ることは難しいです(GCがクロージャを除去して配列をきれいにするのに十分速いのですか?)しかし、このコードは本当に問題を募集しています。 **決してタスクの実行を待つためにタイムアウトを使用しないでください。 –

+0

"私は前のタイムアウトが完了するのに十分な10ミリ秒を待っています_なぜそれをお考えですか? – KarelG

+0

コンソールログを追加すると、そのことを確認できます。まだconsole.logでメモリリークが発生する – Karamell

答えて

0

ここにループがあります。そして最初の文は、読み取ります

while (true) { 
    let giantArray = Array(100000).fill().map(() => Math.random()); 

ですから、各ループの反復で新しい giantArrayを作成しています。その後すぐに捨てられる。そしてあなたはこれがあなたを「記憶不足」に動かすことに本当に驚いていますか?

他の言い方をすれば、後で何をするかは本当に問題ではありません。あなたのコードはその巨大な配列を作成します。それを埋める(!);それを投げ捨てる。そして同じことを何度も何度もやります。

ガーベッジコレクションが正しく動作する場合でも(そうでない場合でも)。ガベージコレクタが追いつくことができないような高いレートでゴミを作成することはまだ可能です!

+0

setTimeoutがなくてもgiantArrayを参照していてもメモリリークはありません – Karamell

関連する問題