jQuery.remove(), detach DOM elements, but I still

2019-04-21 14:43发布

问题:

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.

回答1:

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