JavaScript garbage collection

I need help here to understand how this works (or not, for that matter).

  • On a webpage, I create a click event listener for node.
  • Inside the listener, I create an instance of some random class that sets the node as property inside itself. So, if var classInstance is an instance, I can access the node somehow like classInstance.rootNode .
  • When the listener starts, I configure the ajax request, keep classInstance in close, and pass the ajax response to classInstance and use it to possibly change the style or contents of rootNode or something else.

My question is, as soon as I finished with classInstance , believing that nothing else refers to it in itself, it does not contain anything else in its closure, can the garbage collector get rid of it? If not, how can I mark it for deletion?

+4
source share
2 answers

In response to @ Beetroot-Beetroot doubts (which, admittedly, I have too), I did some more digging. I installed this script and used the chrome dev-tools' timeline in this article as a guide. In a fiddle, two almost identical handlers create a closure with two date objects. The first links are a , the second refers to both a and b . Although in both cases only a can really be set (hard-coded values), the first close uses significantly less memory. Regardless of whether it is JIC (only at compile time) or V8 JS optimization, I can not say for sure. But from what I read, I would say that it is a V8 GC that frees b when the tst function tst , which it cannot in the second case ( bar refers to b when tst2 returns). I have a feeling that this is not so wild, and I would not be surprised to know that FF and even IE will work in a similar way.
Just adding this, possibly irrelevant, update for completeness and because I feel that the link to Google documentation on dev-tools is an added value.


It depends on a simple rule: as long as you can no longer refer to the classInstance variable, it must be GC'ed, regardless of your own circular references. I tested quite a few constructs similar to the one you describe here. Maybe it's worth a look
I found that closures and mem leaks are not so common or easily accessible (at least not more),

But since the accepted answer says: it's almost impossible to find out when the code will leak.
Re-reading your question, I would say: no, you are not going to leak a memory: the classInstance variable classInstance not been created in the global scope, but it is passed to various functions (and, therefore, various fields of application). These areas fall apart every time the function returns. classInstance will not be GC'ed if it is passed to another function / scope. But as soon as the last function referencing classInstance , the object is tagged for GC. Of course, this may be a circular link, but it is a link that cannot be accessed anywhere except in its own area.
You cannot call it closure: closure occurs when there is some form of external impact, which does not happen in your example.

I painfully explain such things, but simply repeat:

 var foo = (function() { var a, b, c, d; return function() { return a; } })(); 

GC will remove the link mem b , c and d : they are out of scope, there is no access to them ...

 var foo = (function() { var a, b, c, d; return function() { a.getB = function() { return b; } a.getSelf = function() { return a;//or return this; } return a; } })(); //some code foo = new Date();// 

In this case, b for obvious reasons, will not get GC'ed. foo provides a and b , where a is an object containing a circular reference. Although, as soon as foo = new Date() , foo loses the reference to a . Of course, a still refers to itself, but a no longer affected: he can refer to everything that he likes. Most browsers do not care and will be GC a and b . In fact, I checked both Chrome, FF and IE8 all the GC code above is fine ... no worries, then.

+6
source

I am not an expert on this issue, but I am sure that the GC will not get rid of it. In fact, it probably will never be, because you created a circular link between the event listener and the DOM node. To enable garbage collection, you must set one or both of these links (event listener and / or rootNode) to undefined or null.

However, I would only worry about this if you were creating many of these class events, or if you could create them several times in the life of the page. Otherwise, this is unnecessary optimization.

+1
source

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


All Articles