Bug Tracker

Modify

Ticket #6583 (closed bug: invalid)

Opened 3 years ago

Last modified 15 months ago

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:
Blocking: Blocked by:

Description (last modified by snover) (diff)

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

jQuery memory retention.zip Download (28.4 KB) - added by huntc 3 years ago.
Reproducible test case
jQuery memory retention 6583 fix.zip Download (49.7 KB) - added by huntc 3 years ago.
A patch of the 1.4.2 source that attends to the issue.

Change History

Changed 3 years ago by huntc

Reproducible test case

comment:1 Changed 3 years ago by huntc

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 3 years ago by huntc

A patch of the 1.4.2 source that attends to the issue.

comment:2 Changed 3 years ago by huntc

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.

comment:3 Changed 3 years ago by huntc

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;

comment:4 Changed 3 years ago by snover

  • Milestone 1.4.3 deleted

Resetting milestone to future.

comment:5 Changed 3 years ago by snover

  • Keywords leak added; retention removed
  • Priority set to undecided
  • Status changed from new to open
  • Description modified (diff)

comment:6 Changed 3 years ago by snover

  • Priority changed from undecided to blocker
  • Version changed from 1.4.2 to 1.4.4
  • Milestone set to 1.4.5

comment:7 Changed 3 years ago by snover

  • Status changed from open to closed
  • Resolution set to invalid

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.

Last edited 3 years ago by snover (previous) (diff)

comment:8 Changed 3 years ago by huntc

Replying to 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?

comment:9 Changed 2 years ago by john

  • Version changed from 1.4.4 to 1.5

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

comment:10 Changed 2 years ago by john

  • Milestone changed from 1.4.5 to 1.5

There was no 1.4.5 release, was actually 1.5.

Please follow the  bug reporting guidlines and use  jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.

View

Add a comment

Modify Ticket

Action
as closed
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.