3

chrome 開発ツールを使用して、モジュールの概念を使用するアプリケーションが、他のアプリケーション オブジェクトから直接参照されていなくても、一部の Module オブジェクトがメモリ内に残っていることを最近知りました。

ここでの問題は、それらがいくつかの関数スコープで参照されていることです。

次のスクリーンショットでわかるように:

ここに画像の説明を入力

関数スコープには多くの参照が保持されています。

これは、私のアプリケーションでこれがどのように行われるかを示すコードの一部です。module内部で参照されているためsomeCallback、参照があり、自分自身を削除できません。

function augmentModule(core, module){

   var someCallback = function(){
      module.stop();
   };

   module.listenTo(core, "someEvent", someCallback);
}

私の質問は:

これは私が心配しなければならない本当のメモリ リークですか、それともこのオブジェクトは後で JavaScript エンジンによってガベージ コレクションされるのでしょうか? JavaScript エンジンは、「このオブジェクトは関数スコープとクロージャー スコープからのみ参照され、「実際の」参照がないため削除できる」ことを認識していますか。?

4

3 に答える 3

2

あなたの例では、実際の問題はありません。変数「モジュール」は関数から参照されるため、誰かが関数を保持している限り保持されます。関数が呼び出されると、このオブジェクトが必要になるため、これは絶対に正当です。関数がリリースされると、この参照はなくなります。

ただし、より微妙なことに注意する必要があります。メイン関数内に複数のクロージャーが必要な場合、それらはすべて 1 つのスコープ ストレージを共有します。これは、いくつかの参照をクロージャーに保持することができ、それらを必要としないことを意味します:

function m(ref0, ref1, ref2, ref3) {
   var cb1 = function(){
     return ref1 + ref2;
   };
   function notCurentlyUsed(){
     return ref2 + ref3;
   };
   ref0.doSomething();
   return cb1;
}

そう、

  • ref0 はクロージャとは関係なく、m が終了すると解放されます。
  • ref1 は保持され、cb1 で必要とされるため、cb1 によって保持されるスコープ ストレージに入ります。
  • ref2 は保持され、cb1 と notCurentlyUsed の両方で必要とされるため、cb1 によって保持されるスコープ ストレージに入ります。
  • ref3 も保持されます。これは notCurentlyUsed によってのみ必要とされますが、スコープ構造は共有されるため、cb1 によっても保持されます。

関数値はその .

于 2013-05-14T22:37:22.463 に答える
2

1 つの方法は、モジュールのサブクラス (augmenModule) にティアダウン メソッドを実装することです。ティアダウン メソッドは、初期化時にクラスによってセットアップされたすべてのオブザーバー関数のバインドを解除します。オブジェクトを破棄するときは、teardown メソッドを呼び出して参照を解放し、関連するメモリをガベージ コレクションできるようにします。

于 2013-05-08T04:34:00.880 に答える
0

距離が最小の一番上のリテーナーのツリーを展開してください。実際、このツリーは、オブジェクトを存続させるグラフの一部です。

したがって、収集する必要がある「モジュール」オブジェクトへの直接的または間接的な参照を保持するアプリの設計によって生きている必要がある保持ツリー内のオブジェクトを見つける必要があります。この参照が問題の根本になります。そのような参照がたくさんある可能性があります。その場合、それらをすべて削除する必要があります。

于 2013-05-11T05:58:46.717 に答える