2011-07-25 5 views
18

は、だから私は、コードのこの部分を発見し、それは明らかに動作します:自己破砕Javascript機能 - どのように機能するのですか? (それは年間の生産であったように)

知りたい
window[someMethod] = function (tmp) { 
    callback({prop:"val"}, tmp); 

    // Garbage collect 
    window[someMethod] = undefined; 
    try { 
     delete window[someMethod]; 
    } 
    catch (e) { } 
    if (head) { 
     head.removeChild(script); 
    } 
    // head refers to DOM head elem and script refers to some script file elem 
}; 

、それがどのように動作しますか?

  1. それはどのように delete自体にその本体内undefinedtryに自分自身を設定することができますか?
  2. 呼び出しが完了するまで、ブラウザはundefineddeleteを実行しないことを知っていますか?そしてどうやって?
  3. ブラウザがすぐに削除すると、その後何が起こりますか?最後の行は走っていますか?
  4. 最後に、この漏れたメモリが見えますか?はいの場合、どうですか?

答えて

21
  1. 自身をに設定していないため、自分自身への参照が未定義に設定されています。関数をメモリ内のコードブロックと考えると、そのコードブロックはこの場合は削除されず、参照のみが削除されます。 JavaScriptで明示的に何かを削除することは決してありません。単純に参照を削除し、ガベージコレクタに残してクリーンアップします。これは、実際のコード、ヒープオブジェクト、エンジンまでの扱い方(解釈、コンパイル、そろばんなど)
  2. そのロジックに基づいて、一度その関数が実行されているときには、最初に実行を転送するためだけに必要とされたため、元の参照が不要になります。
  3. あなたは、JSの評価がすべてのステートメントについてそれを参照する必要があると誤解しています。おそらく、このメソッドはJust-In-Timeでコンパイルされており、他のJS以​​外の関数が実行されるように実行されています。
  4. 上記のコードには明らかなメモリリークはありません。

うまくいけば、これは意味をなさないでしょう。

+1

コールバック関数がどこかの 'tmp'への参照を保持していても、なぜメモリリークが起こるのかわかりません。 –

+1

あなたはおそらく正しいでしょう。 – yan

+0

これは非常に役に立ちます。私は今日これを掲示する前にbrainfartを持っていたように感じる! – Mrchief

2

ウィンドウ[someMethod]は単なる参考情報です。参照のみが削除され、関数自体は削除されません。 関数が完了し、関数へのすべての参照が削除されると、メモリリークを避けるためにガベージコレクションが処理される必要があります。

3

を明示的にで削除することはできません.Javascriptで何かを削除してください。すべての参照を削除するだけで、ガベージコレクタに次のサイクルで削除させることができます。この関数が終了すると、関数自体はメモリに残っていますが、関数への外部参照はありません。次回GCが実行されると、これが検出され、そのメモリの割り当てが解除されます。

関連する問題