Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove DOM elements without memory leaks?

My JavaSript code builds a list of LI elements. When I update the list, memory usage grows and never goes down. I tested in sIEve and it shows that the browser keeps all elements that were supposed to be deleted by $.remove() or $.empty jQuery commands.

What should I do to remove DOM nodes without the memory leak?

See my other question for the specific code.

like image 795
podeig Avatar asked Sep 24 '10 08:09

podeig


People also ask

How do I completely remove an element from a DOM?

To remove an element from the DOM, you can also use the remove() method of the element. How it works. First, select the last element of the ul element. Second, call the remove() of that element to remove it from the DOM.

How do you grab elements from DOM?

The easiest way to access a single element in the DOM is by its unique ID. You can get an element by ID with the getElementById() method of the document object. In the Console, get the element and assign it to the demoId variable. Logging demoId to the console will return our entire HTML element.

What is a detached DOM element?

Detached DOM elements are the elements which have been removed from the DOM but their memory is still retained because of JavaScript. This means that as long the element have a reference to any variable or an object anywhere, it does not garbage collected even after destroyed from the DOM.


2 Answers

The DOM preserves all DOM nodes, even if they have been removed from the DOM tree itself, the only way to remove these nodes is to do a page refresh (if you put the list into an iframe the refresh won't be as noticable)

Otherwise, you could wait for the problem to get bad enough that the browsers garbage collector is forced into action (talking hundreds of megabytes of unused nodes here)

Best practice is to reuse nodes.

EDIT: Try this:

var garbageBin; window.onload = function ()     {     if (typeof(garbageBin) === 'undefined')         {         //Here we are creating a 'garbage bin' object to temporarily          //store elements that are to be discarded         garbageBin = document.createElement('div');         garbageBin.style.display = 'none'; //Make sure it is not displayed         document.body.appendChild(garbageBin);         }     function discardElement(element)         {         //The way this works is due to the phenomenon whereby child nodes         //of an object with it's innerHTML emptied are removed from memory          //Move the element to the garbage bin element         garbageBin.appendChild(element);         //Empty the garbage bin         garbageBin.innerHTML = "";         }     } 

To use it in your context, you would do it like this:

discardElement(this); 
like image 88
Randy the Dev Avatar answered Sep 26 '22 06:09

Randy the Dev


This is more of an FYI than an actual answer, but it is also quite interesting.

From the W3C DOM core specification (http://www.w3.org/TR/DOM-Level-2-Core/core.html):

The Core DOM APIs are designed to be compatible with a wide range of languages, including both general-user scripting languages and the more challenging languages used mostly by professional programmers. Thus, the DOM APIs need to operate across a variety of memory management philosophies, from language bindings that do not expose memory management to the user at all, through those (notably Java) that provide explicit constructors but provide an automatic garbage collection mechanism to automatically reclaim unused memory, to those (especially C/C++) that generally require the programmer to explicitly allocate object memory, track where it is used, and explicitly free it for re-use. To ensure a consistent API across these platforms, the DOM does not address memory management issues at all, but instead leaves these for the implementation. Neither of the explicit language bindings defined by the DOM API (for ECMAScript and Java) require any memory management methods, but DOM bindings for other languages (especially C or C++) may require such support. These extensions will be the responsibility of those adapting the DOM API to a specific language, not the DOM Working Group.

In other words: memory management is left to the implementation of the DOM specification in various languages. You would have to look into the documentation of the DOM implementation in javascript to find out any method to remove a DOM object from memory, which is not a hack. (There is however very little information on the MDC site on that topic.)


As a note on jQuery#remove and jQuery#empty: from what I can tell neither of these methods does anything other than removing Objects from DOM nodes or removing DOM nodes from the document. They only remove That of course does not mean that there is no memory allocated to these objects (even though they aren't in the document anymore).

Edit: The above passage was superfluous since obviously jQuery cannot do wonders and work around the DOM implementation of the used browser.

like image 42
FK82 Avatar answered Sep 22 '22 06:09

FK82