Javascript – Using jQuery and Memory Leaks

closuresjavascriptjquerymemory-leaks

I have been using jQuery for over a couple of months and read up on Javascript memory leaks for a few days.
I have two questions regarding memory leaks and jQuery:

  1. When I bind (using .bind(…)) do I have to unbind them (.unbind()) if I leave the page/refresh to avoid memory leaks or does jQuery remove them for me?

  2. Concerning closures, I read that they can lead to memory leaks if used incorrectly. If I do something such as:

    function doStuff( objects ){ //objects is a jQuery object that holds an array of DOM objects
    var textColor = "red";
    objects.each(function(){
    $(this).css("color", textColor );
    });
    }

    doStuff( $( "*" ) );

I know that the above code is stupid (better/simpler r ways of doing this) but I want to know if this causes circular references/closure problems with .each and if it would cause a memory leak. If it does cause a memory leak, how would I rewrite it (usually similar method) to avoid a memory leak?

Thanks in advance.

Edit: I have another case similar to question 2 (which I guess makes this part 3).

  1. If have something like this:

    function doStuff( objects ){ //iframe objects
    var textColor = "red";

    function innerFunction()
    {          
        $(this).contents().find('a').css("color", textColor );
    }
    
    objects.each(function(){   
        //I can tell if all 3 are running then we 
        //have 3 of the same events on each object, 
        //this is just so see which method works/preferred
    
        //Case 1
        $(this).load(innerFunction);
    
        //Case 2
        $(this).load(function(){
           $(this).contents().find('a').css("color", textColor );
        });
    
        //Case 3  
        $(this).load(function(){
           innerFunction();
        });
    });
    

    }
    doStuff( $( "iframe" ) );

There are 3 cases above and I would like to know which method (or all) would produce a memory leak. Also I would like to know which is the preferred method (usually I use case 2) or better practice (or if these are not good what would be better?).

Thanks again!

Best Answer

1) No. The browser clears everything between page loads.

2) In its current form there will be no memory leak, since jquery's .each() function doesn't bind anything, so once its execution is finished, the anonymous function it was passed is no longer reachable, and therefore the environment it closed (i.e. the closure as a whole) is also not reachable. So the garbage collection engine can clean everything up - including the reference to objects.

However, if instead of .each() you had something harmless, like $('div:eq(0)').bind() (I'm trying to emphasise that it needn't be a reference to the large objects variable, enough that it is even a single unrelated element), then since the anonymous function sent to .bind() closes the objects variable, it will remain reachable, and therefore not garbage collected, allowing memory leaks.

A simple way to avoid this problem, is to objects = null; at the end of the executing function.

I should note that I'm not familiar with the JS garbage collection engines, so it is possible that there are reasonably intelligent optimisations. For example it can be checked whether or not the anonymous function tries to access any variables closed in with it, and if not, it might pass them to the garbage collector, which would solve the problem.

For further reading, look for references to javascript's memory model, specifically the environment model and static binding.