2016-11-17 4 views
1
は、私はjsのベストプラクティスと一般的なミスにまで読んできた、と私は https://www.toptal.com/javascript/10-most-common-javascript-mistakes

このjsコードはどのようにメモリをリークしますか?

var theThing = null; 
var replaceThing = function() { 
    var priorThing = theThing; // hold on to the prior thing 
    var unused = function() { 
     // 'unused' is the only place where 'priorThing' is referenced, 
     // but 'unused' never gets invoked 
     if (priorThing) { 
      console.log("hi"); 
     } 
    }; 
    theThing = { 
     longStr: new Array(1000000).join('*'), // create a 1MB object 
     someMethod: function() { 
      console.log(someMessage); 
     } 
    }; 
}; 

からのコードのこの作品に出会った

私は、コンソールにこのコードを入力するとreplaceThing()を複数回呼び出して、真の十分な試みたが、 Chromeタスクマネージャのメモリ使用量はGC後も上がります。

クロージャunusedは、priorThingへの参照を保持しているため、GCに適格ではありません。しかし:

priorThing = theThingが実行される
  1. は、unusedクロージャ内の参照は、theThingにも変化しないのですか?
  2. #1が当てはまらない場合でも、の実行が終了すると、変数unusedはスコープから外れてはなりませんか?

答えて

1

はいメモリリークがあります。これは、クロージャがJavascriptで実装される方法によって異なります。すべての関数オブジェクトには、そのレキシカルスコープを表す辞書スタイルのオブジェクトへのリンクがあります。 IF A VARIABLE IS USED IN ONE CLOSURE, IT ENDS UP IN THE LEXICAL SCOPE SHARED BY ALL OTHER CLOSURES IN THAT SCOPE。この場合、同じ範囲内に2つのクロージャーtheThingunusedがあります。 unusedpriorThingを使用すると、priorThingは、unusedが呼び出されていないのと同じように、クロージャの変数であり、priorThingtheThingのクロージャに含まれます。したがってpriorThingは、replaceThingが返された後にガベージコレクションされません。 priorThing = theThingが実行されると、古いtheThing値をpriorThingに格納されている

1)のでunused私はコンソールの機能の範囲を見てみました新たに作成したもの

+0

theThing古くないことをいいます。私の理解は正しいのですか?theThingのsomeMethodクロージャが作成されると、未使用の参照が保持され、それ自体がpriorThingへの参照を保持します。 priorThing自体はsomeMethodの前のバージョンを含んでおり、未使用の前のバージョンには、最初のオブジェクトへの参照チェーンを形成していますか? –

+0

yah that right understand – henrybbosa

+0

JavaScriptの厄介な部分 – henrybbosa

関連する問題