@Beetroot-Beetroot の疑問 (確かに、私もそうです) に応えて、さらに掘り下げました。このフィドルを設定し、chrome dev-tools のタイムラインとこの記事をガイドラインとして使用しました。フィドルでは、2 つのほぼ同一のハンドラーが 2 つの日付オブジェクトでクロージャーを作成します。最初は のみを参照a
し、2 番目は と の両方a
を参照しb
ます。どちらの場合も、a
実際に公開できるのは (ハードコードされた値) だけですが、最初のクロージャは使用するメモリが大幅に少なくなります。これが JIC (ジャスト イン タイム コンパイル) によるものなのか、V8 の JS 最適化ウィザードによるものなのか、はっきりとは言えません。しかし、私が読んだことから、V8 の GC が割り当てを解除b
するのは、tst
関数は戻りますが、2 番目のケース (戻り時にbar
参照) ではできません。これはそれほど風変わりではないと感じています。FF や IE でさえ同様に機能することを知っても、まったく驚かないでしょう。完全を期すために、おそらく関係のないこの更新を追加しました。これは、開発ツールに関するGoogleのドキュメントへのリンクがある種の付加価値であると感じているためです。b
tst2
簡単な経験則として、依存classInstance
関係があります。変数を参照できない限り、それ自体の循環参照に関係なく、GC する必要があります。ここで説明したものと同様に、かなり多くの構造をテストしました。おそらく、
クロージャーとメモリリークはそれほど一般的ではないか、簡単に手に入れることができないことがわかりました(少なくとも、もうそうではありません)。
しかし、受け入れられた答えが言うように、どのコードがいつリークするかを知ることはほとんど不可能です.
あなたの質問をもう一度読んで、私は言います:いいえ、あなたはメモリをリークするつもりはありません.classInstance
変数はグローバルスコープで作成されていませんが、さまざまな関数(したがってさまざまなスコープ)に渡されています. これらのスコープは、関数が戻るたびに分解されます。classInstance
別の関数/スコープに渡された場合、GC されません。ただし、参照する最後の関数が戻るとすぐにclassInstance
、オブジェクトは GC のマークが付けられます。確かに循環参照かもしれませんが、独自のスコープ以外からはアクセスできない参照です。
それを実際に閉鎖と呼ぶこともできません。閉鎖は、何らかの形で露出がある場合に発生します。あなたの例では起こっていません。
私はこのようなことを説明するのはばかげていますが、要約するだけです:
var foo = (function()
{
var a, b, c, d;
return function()
{
return a;
}
})();
GC は mem と参照の割り当てを解除しb
ますc
:d
それらは範囲外にあり、それらにアクセスする方法はありません...
var foo = (function()
{
var a, b, c, d;
return function()
{
a.getB = function()
{
return b;
}
a.getSelf = function()
{
return a;//or return this;
}
return a;
}
})();
//some code
foo = new Date();//
この場合、b
明らかな理由から、どちらも GC されません。およびをfoo
公開します。ここで、は循環参照を含むオブジェクトです。とすぐに、への参照が失われます。確かに、まだ自分自身を参照していますが、もはや公開されていません。好きなものを参照できます。ほとんどのブラウザーは気にせず、GCと. 実際、Chrome、FF、およびIE8 はすべて、上記のコードを完全に GC することを確認しました...心配はいりません。a
b
a
foo = new Date()
foo
a
a
a
a
b