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 comment:1
Changed May 22, 2010 02:07AM UTC by 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 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 comment:4
milestone: | 1.4.3 |
---|
Resetting milestone to future.
Changed November 21, 2010 04:52AM UTC by 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 timeout → memory leak ajax timeout |
priority: | → undecided |
status: | new → open |
Changed November 21, 2010 04:52AM UTC by comment:6
milestone: | → 1.4.5 |
---|---|
priority: | undecided → blocker |
version: | 1.4.2 → 1.4.4 |
Changed December 03, 2010 08:11AM UTC by 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: | open → closed |
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 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 comment:9
version: | 1.4.4 → 1.5 |
---|
There wasn't a 1.4.5 release, was actually 1.5.
Changed January 31, 2011 05:54PM UTC by comment:10
milestone: | 1.4.5 → 1.5 |
---|
There was no 1.4.5 release, was actually 1.5.
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.