If i have a function like this
function do(callback) {
//do stuff
callback();
}
and then I pass in an anonymous function:
do(function() { //do something else });
does that anonymous function ever get collected during the lifespan of the page? If not, how can i make it available for GC?
do I have to do this?
var h = function() { //do something };
do(h);
delete h;
Do I even have to worry about this? I am building a web app that has a long lifespan, makes a lot of ajax calls keeps objects for a while and doesn't really require a page refresh to navigate thru. So I'm trying to figure out if I might fall into a memory leak monster.
The only reference to the anonymous function is the function argument, and that disappears when the function finishes, so your callback will be available for garbage collection after that. Except when something else gets a reference to it, which can happen easily with closures:
function doo(callback) {
$.get(url, function() {
// callback is visible here!
});
callback();
}
doo(function() { /* do something else */ });
callback
(along with the whole scope created by calling doo
) must stay in the memory, because the inner function can reference it through the closure; it can only be garbage collected when the inner function is garbage collected, and since that function is a property of the jqXHR object, that object must be garbage collected before that, and who knows when that will happen...
Update You can avoid unnecessary closures by not defining your functions inside other functions:
var func = function() {
// callback is not visible here
}
function doo(callback) {
$.get(url, func);
callback();
}
doo(function() { /* do something else */ });
Watch out for circular references, otherwise the GC for the browser will clean those up. Closures make it really easy to create a circular reference, and that might be trapped in memory even if you browse away from the page that created it. So, web applications that stay on-screen for long periods of time are especially vulnerable.
Check out the section "Memory leaks" here: https://developer.mozilla.org/en/A_re-introduction_to_JavaScript.
I've designed quite a few static-page web applications. I've found that even when you don't have to clean up objects and event handlers (ie you're sure there is no circular reference), it can't hurt. It usually only adds a couple of extra lines of code, and it keeps memory use and efficiency at the forefront of your mind as you write your code. This is something of a shift for web developers because we usually don't have to think about this kind of thing very much when creating a website.