I need some help here to undestand how this works (or does not, for that matter).
var classInstance
is the instance, I can access the node as something like classInstance.rootNode
.classInstance
in closure and pass along the ajax response to classInstance
and use it to perhaps modify the rootNode
's style or content or whatever.My question is, once I'm done with classInstance
, assuming nothing else references it and by itself, it holds nothing else in its own closure, will the garbage collector dispose of it? If not, how do I mark it for disposal?
In response to @Beetroot-Beetroot's doubts (which, admittedly, I have, too), I did some more digging. I set up this fiddle, and used the chrome dev-tools' timeline and this article as a guideline. In the fiddle, two almost identical handlers create a closure with 2 date objects. The first only references a
, the second references both a
and b
. Though in both cases only a
can ever really be exposed (hard-coded values), the first closure uses significantly less memory. Whether or not this is down to JIC (just in time compilation) or V8's JS optimization wizardry, I can't say for sure. But from what I've read, I'd say it's V8's GC that deallocates b
when the tst
function returns, which it can't in the second case (bar
references b
when tst2
returns). I get the feeling that this isn't that outlandish, and I wouldn't at all be surprised to find out that FF and even IE would work similarly.
Just added this, perhaps irrelevant, update for completeness' sake and because I feel as though a link to google's documentation of the dev-tools is an added value of sorts.
It sort of depends, as a simple rule of thumb: as long as you can't reference the classInstance
variable anymore, it should be GC'ed, regardless of its own circular references. I've tested quite a lot of constructions, similar to the one you describe here. Perhaps it's worth a look
I've found that closures and mem-leaks aren't that common or easy to get by (at least, not anymore).
But as the accepted answer says: it's nigh impossible to know when what code will leak.
Reading over your question again, I'd say: no, you're not going to leak memory: the classInstance
variable wasn't created in the global scope, but it's being passed to various functions (and therefore various scopes). These scopes disintegrate each time the function returns. classInstance
won't be GC'ed if it's been passed to another function/scope. But as soon as the last function that references classInstance
returns, the object is marked for GC. Sure it might be a circular reference, but it's a reference that cannot be accessed from anywhere but its own scope.
You can't really call that a closure, either: closures happen when there is some form of exposure to the outer scope, which is not happening in your example.
I'm rubbish at explaining stuff like this, but just to recap:
var foo = (function()
{
var a, b, c, d;
return function()
{
return a;
}
})();
The GC will deallocate the mem b
,c
and d
reference: they've gone out of scope, there's no way to access 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
won't get GC'ed either, for obvious reasons. foo
exposes a
and b
, where a
is an object that contains a circular reference. Though as soon as foo = new Date()
, foo
loses any reference to a
. Sure, a
still references itself, but a
is no longer exposed: it can reference whatever it bloody well likes. Most browsers won't care and will GC a
and b
. In fact, I've checked and Chrome, FF, and IE8 all GC the code above perfectly... no worries, then.
I'm not an expert on this issue, but I'm pretty sure the GC will not dispose of it. In fact, it probably never will, because you've created a circular reference between the event listener and the DOM node. To allow it to be garbage-collected, you should set one or both of those references (the event listener and/or rootNode) to undefined or null.
Still, I'd only worry about this if you're creating many of these classInstances or if it can be created several times over the page's lifetime. Otherwise it's an unnecessary optimization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With