5

とりわけ、いくつかのDOMノードを作成することを仕事とするコンポーネントがあるとします(たとえば、jqueryを使用)。

function PageFiller() {
}
PageFiller.prototype.fillPage = function () {
  this.dom = $("<div/>", {
    "class" : "hello",
    text : "Hello world"
  });
  $("body").append(this.dom);
}

「PageFiller」への参照を保持せずに、別のコンポーネントがこれを使用してDOMを埋めるとします。

function Main() {
}
Main.prototype.start = function () {
   var filler = new PageFiller();
   filler.fillPage();
};
var main = new Main()
main.start();

その直後に(同じスコープで)誰かが残酷にDOMをクリアするとは思わないでください:

$(".hello").remove();

そのような状況でのメモリレイアウトは何ですか?PageFillerインスタンスでメモリリークが発生しましたか?

PageFillerインスタンスは、もう存在しないDOMの一部を表すjqueryオブジェクトへの参照を保持しているため、どの時点でガベージコレクションが行われるのか(発生した場合)は少しわかりません。または、実際のDOMオブジェクトは通常のJS変数とは異なるヒープに存在することを私が理解しているので、それはDOMとは何の関係もありません(ここで間違っていない限り)。

更新:PageFillerへの参照がMainオブジェクトによって保持されている場合、そのバリエーションは次のようになります。

Main.prototype.start = function () {
    this.filler = new PageFiller();
    filler.fillPage();
}

この状況では、MainオブジェクトにはPageFillerオブジェクトへの参照があり、PageFillerオブジェクト自体はJQオブジェクトへの参照を保持しています。'remove'の後、JQオブジェクトはまだメモリに存在しますが、存在しないDOMノードを指しています。

元の例では、main.start()が終了するとすぐに次のように言うのは正しいですか?

  • PageFillerオブジェクトへの参照を保持するオブジェクトはないため、ガベージコレクションが実行され、pageFiller.domオブジェクトは誰からも参照されないため、ガベージコレクションも実行されますか?
  • 実際のDOM要素は明らかにメモリ内に存在しますが、別のヒープ内にあるため、実際に心配する必要はありません。

その他の場合:

今回は、問題を複雑にするイベントハンドラーを使用した小さなバリエーションです。

PageFiller.prototype.fillPage = function () {
  var self = this;
  this.dom = ... // as usual 
  this.dom.click(function () {
    alert("Just clicked on dom generated by " + self);
  });
}

今回は、PageFillerインスタンスをスコープ外に実行するだけでは、クリックハンドラーで使用されるクロージャーによって参照されるため、メモリを再利用するのに十分ではありませんでした。ここでメモリリークが発生しましたか?または、$( "")。remove()呼び出しを信頼して、クロージャーへの参照を強制終了し、PageFillerへの最後の参照を強制終了できますか?また、jqueryを使用せずに(ネイティブDOM APIを使用して)要素を削除した場合、動作が異なりますか?

これはおそらくすべて私が望むように機能しますが、私はこのパターンからメモリがリークすることはないことを自分自身に確信させようとしています。

ありがとう。

4

1 に答える 1

1

更新しました

filler.dom一度終了した を削除するmain.start()と、保持しているノードの参照カウントが減少します。これは、ノードを所有していないためです (つまり、弱いプロパティ)。

$().remove()refcount を再度呼び出したときに実際のノードが削除されると、ゼロに減少し、ガベージ コレクションが可能になります。

ですから、AFAICT では何も心配する必要はありません。

于 2012-05-30T16:50:38.953 に答える