Skip to main content

Bug Tracker

Side navigation

#6583 closed bug (invalid)

Opened May 19, 2010 12:03PM UTC

Closed December 03, 2010 08:11AM UTC

Last modified March 13, 2012 09:06PM UTC

Memory retention caused by the use of timeout in ajax call

Reported by: huntc Owned by:
Priority: blocker Milestone: 1.5
Component: ajax Version: 1.5
Keywords: memory leak ajax timeout Cc:
Blocked by: Blocking:
Description

I find that when using the timeout option in an ajax call, and an error state is reached, and then followed by another call via a timer, memory is being retained. I have observed this on Mac OS X using Safari and Firefox. Here is a snippet of code that will reproduce the problem (I have also attached a complete project):

function get() {
  $.ajax({
    url: "file:///thisshouldfail",
    timeout: 1000,
    error: function(XMLHttpRequest, textStatus, errorThrown) {
      setTimeout(get, 100);
    }
  });
}

$(document).ready(function() {
  get();
});

To see the memory being retained please investigate the browser's resident memory size e.g. use the Unix 'top' command.

Attachments (2)
Change History (10)

Changed May 20, 2010 03:45AM UTC by huntc comment:1

I've managed to identify the issue. If you receive an error and there is then a timeout i.e. the jQuery ajax timer fires (which it will if a timeout is specified), jQuery thinks that the request has not been completed. The error handler is then invoked again.

My recommendation is to set requestDone to true as the last statement of the complete() function. In addition I recommend the removal of setting requestDone to true at lines 5172 and 5179 (v.1.4.2 source file); this then keeps the setting of requestDone to just one place.

I have tested the fix and all is well with regards to memory being released.

I attach my modified source.

Changed May 22, 2010 02:07AM UTC by huntc comment:2

I'm also wondering if any timer has been established then the timer should be cancelled by the completion routine. It would be possible for timers to bank up and retain the ajax object for requests that have been previously dealt with. Also, cancelling the timer seems in the completion routine sounds like a nice thing to do.

Changed May 22, 2010 02:19AM UTC by huntc comment:3

I achieve the clearing of the timeout as follows:

__Initialisation__

  var requestDone = false;

  var timeoutId = null;

__Handling timeout__

  // Timeout checker
  if ( s.async && s.timeout > 0 ) {
    timeoutId = setTimeout(function() {
      // Check to see if the request is still happening
      if ( xhr && !requestDone ) {
        onreadystatechange( "timeout" );
      }
    }, s.timeout);
  }

__Completion__

  // Cancel any timer that has been established.
  if (timeoutId != null) {
    clearTimeout(timeoutId);
    timeoutId = null;
  }

  // Completion is recognised by setting requestDone.
  requestDone = true;

Changed November 12, 2010 02:40AM UTC by snover comment:4

milestone: 1.4.3

Resetting milestone to future.

Changed November 21, 2010 04:52AM UTC by snover comment:5

description: I find that when using the timeout option in an ajax call, and an error state is reached, and then followed by another call via a timer, memory is being retained. I have observed this on Mac OS X using Safari and Firefox. Here is a snippet of code that will reproduce the problem (I have also attached a complete project): \ \ function get() { \ $.ajax({ \ url: "file:///thisshouldfail", \ timeout: 1000, \ error: function(XMLHttpRequest, textStatus, errorThrown) { \ setTimeout(get, 100); \ } \ }); \ } \ \ $(document).ready(function() { \ get(); \ }); \ \ To see the memory being retained please investigate the browser's resident memory size e.g. use the Unix 'top' command.I find that when using the timeout option in an ajax call, and an error state is reached, and then followed by another call via a timer, memory is being retained. I have observed this on Mac OS X using Safari and Firefox. Here is a snippet of code that will reproduce the problem (I have also attached a complete project): \ \ {{{ \ function get() { \ $.ajax({ \ url: "file:///thisshouldfail", \ timeout: 1000, \ error: function(XMLHttpRequest, textStatus, errorThrown) { \ setTimeout(get, 100); \ } \ }); \ } \ \ $(document).ready(function() { \ get(); \ }); \ }}} \ \ To see the memory being retained please investigate the browser's resident memory size e.g. use the Unix 'top' command.
keywords: memory retention ajax timeoutmemory leak ajax timeout
priority: → undecided
status: newopen

Changed November 21, 2010 04:52AM UTC by snover comment:6

milestone: → 1.4.5
priority: undecidedblocker
version: 1.4.21.4.4

Changed December 03, 2010 08:11AM UTC by snover comment:7

_comment0: So after investigating this I’m 100% convinced that there is no jQuery bug here—or at least, not in any version of Safari that I have available. \ \ Unfortunately, what I '''have''' confirmed is that Safari appears to leak memory all on its own for '''any''' !XMLHttpRequest (and this leak persists even after a window/tab is closed), no jQuery required, and there’s no way to prevent this from happening because it appears that it happens in the browser chrome (presumably because of the Activity panel). \ \ So, yay for no bug in jQuery, but boo for Safari being a pile of crap with some apparently significant memory leaks related to network requests.1291363915214641
resolution: → invalid
status: openclosed

So after investigating this I’m 100% convinced that there is no jQuery bug here—or at least, not in any version of Safari that I have available.

Unfortunately, what I have confirmed is that Safari appears to leak memory all on its own for any XMLHttpRequest (and this leak persists even after a window/tab is closed), no jQuery required, and there’s no way to prevent this from happening because it appears that it happens in the browser chrome (presumably because of the Activity panel).

So, yay for no bug in jQuery, but boo for Safari being a pile of crap with some apparently significant memory leaks related to network requests.

Changed December 05, 2010 10:32PM UTC by huntc comment:8

Replying to [comment:7 snover]:

So after investigating this I’m 100% convinced that there is no jQuery bug here—or at least, not in any version of Safari that I have available.

Thanks for the follow-up. How about the clearing of the timeout that I identified? Was that at least of interest in terms of being fixed?

Unfortunately, what I have confirmed is that Safari appears to leak memory all on its own for any XMLHttpRequest (and this leak persists even after a window/tab is closed), no jQuery required, and there’s no way to prevent this from happening because it appears that it happens in the browser chrome (presumably because of the Activity panel).

Has this been reported as an issue with WebKit? Can you please substantiate this one further?

Changed January 31, 2011 05:53PM UTC by john comment:9

version: 1.4.41.5

There wasn't a 1.4.5 release, was actually 1.5.

Changed January 31, 2011 05:54PM UTC by john comment:10

milestone: 1.4.51.5

There was no 1.4.5 release, was actually 1.5.