7

I'm using the following pattern which is leaking memory in Firefox:

$(function() {

    (function() {

        var callee = arguments.callee;

        $.ajax({
            url: '...',
            success: function() { ... setTimeout(callee, 1000); },
            error: function() { ... setTimeout(callee, 1000); }
        });

    })();

});

The memory leak remains, even when success/error do nothing other than calling setTimeout again. I'm observing the leak via Windows Task Manager; if the page is left open, memory usage of firefox.exe slowly creeps up. For the final version of this code, I only need to update once a minute, but once-a-second demonstrates the memory leak much faster!

(Note: this looks like a very similar problem to this question, but the selected answer there doesn't appear to cater for Firefox)

Community
  • 1
  • 1
Bobby Jack
  • 15,689
  • 15
  • 65
  • 97
  • what is the function callee doing? are you sure there are no circular references,.? – ovais.tariq Sep 01 '10 at 12:00
  • The 'callee' pattern is just a way of timing code within an anonymous function. Even with the code literally as bare as it is above, there's still a memory leak. – Bobby Jack Sep 01 '10 at 13:55
  • The pattern is discussed in Paul Irish's excellent [Things I learned from the jquery source](http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/) video - see around the 8 minute mark – Bobby Jack Sep 01 '10 at 14:21
  • I have had the same problem try using a queue. – Kapil Sep 14 '10 at 15:51

3 Answers3

4

I was able to reproduce the problem and solved it as such:

$(function() 
{
    function checkStatus() 
    {
        $.ajax({
          url: '...',
          success: function() { ... setTimeout(checkStatus, 1000); },
          error: function() { ... setTimeout(checkStatus, 1000); }
        });

    }

    checkStatus();

});

What appears to happen is each time your anonymous method is called, it creates a variable and assigns a reference to it. Given enough time, this will fill up memory.

This solution just passes the same function ref around rather than creating a new one with each iteration.

Matthew
  • 2,210
  • 1
  • 19
  • 30
0

maybe worth trying something like this?

$(function() 
{
    (function() 
    {
        var callee = arguments.callee;
        $.ajax(
        {
            url: '...',
            success: function() 
            {
                ... 
                setTimeout(function()
                {
                    callee();
                }, 1000);
             },
             error: function() 
             {
                ... 
                setTimeout(function()
                {
                    callee();
                }, 1000);
              }
        });   
    })();
});

so instad of passing calle to the setTimeout callback, pass an anonymous function that calls calle.

Alex Pacurar
  • 5,801
  • 4
  • 26
  • 33
-3

Try putting callee outside of the functions like so:

var callee = arguments.callee;

$(function() {

    (function() {

        $.ajax({
            url: '...',
            success: function() { ... setTimeout(callee, 1000); },
            error: function() { ... setTimeout(callee, 1000); }
        });

    })();

});

So that memory gets allocated only once for "callee", and not everytime the functions are executed.

user258030
  • 399
  • 3
  • 10