开发者

Using jQuery and Memory 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 ob开发者_开发问答jects 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!


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.


There are some subtle leak patterns that you may not even recognize. Check out a question I asked some time ago about a similar issue jQuery 1.5 Memory leak in IE8

If you create a closure around an object which references the dom node, a leaking reference loop is made, and unfortunately, it can not be corrected by simply unbinding. You will have to set the reference to the DOM node in the object to null.


In regards to 1., no, you definitely do not have to .unbind() when leaving a page. I am not entirely sure about two.


About 1, sometimes you have to free your resources especially when you have circular references and using Internet Explorer (because of some bugs, because in theory you shouldn't have to do that) ;) Google maps had a function in their v2 to prevent that that we had to call on document.onunload (GUnload).

About 2, you don't have circular references. It consumes a lot of memory since the this must have its own context of execution to access textColor among others..

A circular reference is achieved when an object references to itself or a closure calls itself. Maybe there's other situations..

Hope this helps

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜