Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery.remove(), detach DOM elements, but I still can access the elements from code. How to avoid leaks?

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.

  1. root and two child contents (child1 and child2)
  2. from child1 I switch to child2, asking my app manager to remove child1 before attaching child2
  3. child2 is being attached (I can see it) but I still can use child1 elements from the code that manages child1

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.

like image 363
giohappy Avatar asked Nov 04 '11 12:11

giohappy


People also ask

Does removing element from DOM remove event listeners?

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.

What is the difference between remove () and detach () methods in jQuery?

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.

Which method is used to remove all the matched element without removing the associated jQuery data?

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.


1 Answers

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

like image 81
Mark Schultheiss Avatar answered Nov 15 '22 12:11

Mark Schultheiss