セットアップ:
obj = object
obj.fun = function
obj.fun.ob = reference to obj
ガベージ コレクタはこのタイプのサイクルを探しますか、それともリークですか?
セットアップ:
obj = object
obj.fun = function
obj.fun.ob = reference to obj
ガベージ コレクタはこのタイプのサイクルを探しますか、それともリークですか?
最新の優れたガベージコレクターは、そのような循環参照を検出できるはずです。むしろ、ガベージコレクションの能力は、そのような参照によって妨げられません(そのようなケースを積極的に探すかどうかは別の話です)。
この問題の影響を受けるナイーブなガベージコレクターの例は、単に参照をカウントし、参照カウントがゼロになったときにのみガベージコレクションを行うものです。ただし、上記で指摘した理由により、これはガベージコレクターが通常実装される方法ではありません。
そこには多くの優れたガベージコレクションアルゴリズムがあり、それ自体が大きなテーマです。
ほとんどの JavaScript ガベージ コレクタは、この種の処理に適したマーク アンド スイープ ガベージ コレクタです。でも:
IE6 以前でobj
は、 が COM オブジェクトでobj.fun
JavaScript 関数の場合、メモリ リークが発生する可能性がありました。IE6 以前では、COM オブジェクトには COM ガベージ コレクター (参照カウンター) を使用し、JavaScript オブジェクトには JavaScript ガベージ コレクター (マーク アンド スイープ コレクター) を使用していました。
IE7 ではまだメモリ リークでしたが、ページがアンロードされたときに収集されていました。ただし、ページがアップしている間は、まだリークする可能性があります。
循環参照自体によってメモリ リークが発生することはありません。これは、メモリ リークに何を含めると考えるかによって少し異なります。現時点では、これらのオブジェクトのいずれかを参照するものがない場合、それらは GC で使用できます。ただし、他の何かが一方を強く参照している場合は、両方が存続します。
メモリリークの通常の原因は、次に設定する場所です
obj.fun = null;
そして、fun が obj への参照を持っていることを忘れて、fun が収集されることを期待します。これはまさに、イベントをフック解除するのを忘れたときに起こることです。