Suppose you have a component whose job is, among other things, to create some DOM node (eg with jquery) :
function PageFiller() {
}
PageFiller.prototype.fillPage = function () {
this.dom = $("<div/>", {
"class" : "hello",
text : "Hello world"
});
$("body").append(this.dom);
}
Suppose that another component uses this to fill the DOM, without keeping a reference to the "PageFiller"
function Main() {
}
Main.prototype.start = function () {
var filler = new PageFiller();
filler.fillPage();
};
var main = new Main()
main.start();
No suppose that right after that (in the same scope), someone brutally clears the DOM :
$(".hello").remove();
What is the memory layout in such a situation ? Have I leaked memory with the PageFiller instance ?
I'm a bit unsure at which point the PageFiller instance would get garbage collected (if it ever happen), since it holds a reference to a jquery object representing part of the DOM that does not exists anymore ? Or does it have nothing to do with the DOM, since from what I understand the actual DOM objects live in a different heap than the regular JS variables (unless I am mistaken here..)
UPDATE : A variation of the thing would be if the reference to the PageFiller was kept by the Main object :
Main.prototype.start = function () {
this.filler = new PageFiller();
filler.fillPage();
}
In this situation, the Main object has a reference to the PageFiller object, which itself holds a reference to a JQ object ; after the 'remove', the JQ object still exists in memory, but points to non-existent DOM nodes, right ?
Am I correct to say that in the original example, as soon as main.start() is finished :
OTHER CASE :
This time a small variation, with event handlers to complicate matters :
PageFiller.prototype.fillPage = function () {
var self = this;
this.dom = ... // as usual
this.dom.click(function () {
alert("Just clicked on dom generated by " + self);
});
}
This time, just letting the PageFiller instance run out of scope could not be enough to have its memory reclaimed, since it is referenced by the closure used in the click handler. Have I leaked memory here ? Or can I trust the $("").remove() call to kill the reference to the closure, hence killing the last reference to the PageFiller ? And would things behave differently if I removed the element without jquery (with the native DOM API ?)
This probably all just work as I hope, but I'm just trying to convince myself that no memory can leak from this pattern.
Thanks.
Updated
Removing the filler.dom
once main.start()
has finished will decrease the refcount for the nodes it's holding on to, because it doesn't own the nodes (i.e. weak property).
When the actual nodes are being removed when you call $().remove()
the refcount again gets decreased to zero and can be garbage collected.
So, AFAICT you should have nothing to worry about.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With