2016-12-21 12 views
3

私が持っている機能:クロームでこれを実行するjavascriptのガベージコレクタがsetTimeout()を収集していませんか?

function test() 
{ 
      for(var i = 0; i < 1000000; i++) 
      { 
       setTimeout(function() 
       { 
        // 
       }, 10000); 
      } 
} 

は、それは私がOKだと思います600メガバイト、50メガバイトの周りからメモリ使用量を推進します。タイムアウトが実行された後、ガベージコレクタはメモリからそれらを削除しないように見えますが、リフレッシュするまで600MBのままです。ページリフレッシュ後に150MBのフットプリントが残っています。

ガベージコレクタに実行後にそれらを取り除くように指示する方法はありますか。

+2

コードの量が少なくても50MBから600MBへのメモリ使用量の向上は問題ありません。あなたは100万回新しいタイマーを作っています。 – petryuno1

+1

も参照してくださいhttp://stackoverflow.com/a/8217000/4769440 –

+0

誰かがこれを試しましたか? 1Mのタイマは実際に600MBの使用量の結果ですか? –

答えて

0

クリーンアップされていないメモリがあると思われます。 問題の私のベスト推測では、このようなループを forに作成すると、 iにアクセスする必要がある新しいスコープが作成されます。したがって、これらの機能は決して浄化されません。 私は間違いを犯しました - 関数は間違いなくクリーンアップされるべきです。私のブラウザでテストしたところ、メモリは900MB以上になりました。

あなたがやっていることをすることにはメリットがないことが重要であり、せいぜい「不良コード」として分類することができます。あなたは一つの関数を作成し、それを再利用する必要があります

// reusing a function fixes the problem 
function test() { 
    var fn = function() {}; 
    for (var i = 0; i < 1000000; i++) { 
     setTimeout(fn, 1000); 
    } 
} 

私の観察は、メモリ使用量が900メガバイトを超えるまで戻って撮影し、その後、徐々に数分にわたって通常に近い状態にまで落ちたということでした。

あなたの関数の中で変数iにアクセスする必要がある場合は、あなたのコードがそれを与えるものではないと言っても大丈夫です。最後にi(1000000)のが表示されます。ファンクション内でiを使用する場合は、ファクトリ関数を使用できます。私のテストでは、メモリが最終的にクリーンアップしまった:あなたはbind使用する場合

// using a factory fixes the problem and give you access to 'i' 
function test() { 
    function factory (n) { 
     return function() { 
      /* This will get called later. 'n' will represent 
       the value of 'i' at the time this function was created */ 
     } 
    } 
    for (var i = 0; i < 1000000; i++) { 
     setTimeout(factory(i), 1000); 
    } 
}; 

残念ながら、メモリの問題が解決しない:ページの更新後に高い残りのメモリ使用量については

// Memory problem still exists with .bind 
function test() { 
    var fn = function (n) { }; 
    for (var i = 0; i < 1000000; i++) { 
     setTimeout(fn.bind(null, i), 1000); 
    } 
} 

を、この私がすることはできません説明していますが、多くのメモリを使用しているように見えるタブ用のメモリを別に置いておくと、ブラウザーの設定が必要になる場合があります。わからない、ちょっと推測する。

+0

"*したがって、これらの関数は決してきれいになりません。*" - 私は従いません。各関数が呼び出されスコープが作成された後は、何も保持しません。 – Bergi

+0

私は "setTimeout(fn、1000);を使用すると、これは混乱しています。それは動作しますが、私が "setTimeout(fn、1000);"それは動作しません? –

+0

@bergi - ありがとう - 私は間違った問題を見ていた。私は私の答えを更新しました。 –

関連する問題