Add / remove listeners in javascript (garbage collector)

I have a quick question regarding adding / removing DOM object listeners. I would like to ask if the garbage collector will be able to collect memory when deleting elements from the page.

ex. <ul> with password for child list ( <li> )

 var ul = document.getElementById('someParent'); var children = ul.children; var someFunction = function() {}; for(var i = 0; i < children.length; i++) { children[i].addEventListener('click', someFunction); } // This is where I am not sure, would the garbage collector be able to collect // the memory allocated on adding listener on children, // if I remove the ul tag? ul.remove(); 
+6
source share
3 answers

Line ul.remove(); will remove the ul element and all its children from the DOM. But memory for event listeners will not be released if you have references to these listeners, elements li and ul . What do you have in the variables children , someFunction and ul .

If you want the garbage collector to clean it all up, you can do, for example:

 ul.remove(); children = null; someFunction = null; ul = null; 

Thus, the children variable will not contain a link to these elements, and if in your code there is no other variable containing a link for these elements, the garbage collector will collect them. The same is true for someFunction . Note that the ul element contains all references to its children and listeners, so ul also needs to be cleared.

+3
source

Not at all, you can access the ul variable elsewhere. The example below shows that.

 var ul = document.getElementById('someParent'); ul.remove(); console.log(ul); // ul and all li tags document.body.appendChild(ul); // ul appears again 

An example is not a normal case. The usual case is that you want to access the DOM link in the event, for example, "click a button." This link will always be available until the event is untied. For instance:

 var ul = document.getElementById('someParent'); var myButton = document.getElementById('myButton'); myButton.addEventListener('click', function () { ul.innerHTML += '<li>Some text</li>' }); ul.remove(); myButton.click(); // no exception when execting button click event 

To avoid memory leak in JS:

  • make sure there are no DOM links using jQuery for Example.
  • If you use DOM links in your application, set them to null or undefined when not in use.

So, you can change your event a bit, as shown below.

 myButton.addEventListener('click', function () { // check ul belongs to visible DOM if (!document.body.contains(ul)) { ul = null; return; } ul.innerHTML += '<li>Some text</li>' }); 
+2
source

If someone can confirm this for me, I will be grateful.

In my opinion, let garbage be collected. According to MDN Memory Management

The basic concepts of garbage collection algorithms rely on the concept of links. In the context of memory management, an object is considered to refer to another object if the former has access to the latter (either implicitly or explicitly). For example, a JavaScript object has a reference to its prototype (implicit reference) and its property values ​​(explicit reference).

Essentially, if the DOM cannot find a link to the specified element, it will collect garbage at some point in the near future. Looking at the standard DOM specification like . Remove () works, it will perform a series of steps that will set new indexes of parents and siblings removing all links to an element.

Since there is no reference to the item mentioned, this will collect garbage. In your example, you add eventListeners only to the children of the specific <ul> element that you created. When you delete an element, you also delete all the links of your child elements (I think this is clearer in the steps in the link above, where they actually set the parent index pointing to itself).

EDIT: @contrabit is right. I have not seen you store your children in a variable. As long as their link to them, they will not collect garbage.

+1
source

Source: https://habr.com/ru/post/981860/


All Articles