I'm aware that it's not easy to correctly manage memory inside an application with lot of UI elements and completely based on Ajax (in my app the pages are never reloaded). But I would like to understand the following behaviour:
I have a root element to which a single child element at a time must be attached (think it as the root element being the app container and the childs the single pages). Whenever I switch between child contents, I remove the previous content with jQuery.remove(), but I see that the content is actually detached from the DOM but it remains in memory.
child1 code (which holds references to child1 DOM):
function testaccess(){
load_and_remove(child2);
var child1DOM = get_this_dom();
}
child1DOM is still there, and I can manipulate it as if it was still attached to the DOM.
Ok, I suppose that jQuery.remove() and the GC won't be able to release memory until I have code that will access it, but even if I don't call get_this_dom(), even after exiting testaccess(), I see that FF memory doesn't decrease...
I wonder how to make GC release all the memory, when I exit child1.
In modern browsers, if a DOM Element is removed, its listeners are also removed from memory in javascript. Note that this will happen ONLY if the element is reference-free. Or in other words, it doesn't have any reference and can be garbage collected. Only then its event listeners will be removed from memory.
remove() removes the matched elements from the DOM completely. detach() is like remove() , but keeps the stored data and events associated with the matched elements.
detach() method is the same as . remove() , except that . detach() keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.
It will not be removed from the DOM until all references to it are released.
You should attempt to remove all circular references between the JS DOM and render DOM - they both have separate garbage collectors and work separately. Hence why the mark and sweep JS garbage collector does not catch those.
You could try to rework your code to break the circular reference:
var mything = something();
mything = null;
Here are a couple of articles that might help:
http://msdn.microsoft.com/en-us/library/Bb250448
http://www.javascriptkit.com/javatutors/closuresleak/index.shtml
http://javascript.info/tutorial/memory-leaks
I am pretty sure you could find some more quite quickly regarding this.
Also, you could try the .empty()
to release all the child nodes but it calls .remove() to do a bit of work.
Note that some of these issues were fixed in newer versions of jQuery i.e. 1.5 is better than 1.4 for instance.
Another post on SO on this: jQuery memory leak with DOM removal
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