Side navigation
#12171 closed bug (patchwelcome)
Opened August 01, 2012 10:54AM UTC
Closed March 16, 2014 05:05PM UTC
Event binding on disconnected element causes memory leak in IE7
Reported by: | johnhunter | Owned by: | |
---|---|---|---|
Priority: | low | Milestone: | 1.next |
Component: | event | Version: | 1.8rc1 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
Creating a disconnected element and then binding an event handler to it causes all subsequent bind calls to leak their elements. When the page is unloaded references remain for every element that has a binding.
Browser: IE7
Test environment: sIEve-0.0.8 (http://home.wanadoo.nl/jsrosman/)
Test case: http://jsfiddle.net/johnhunter/3nFL7/ (will need to run this outside of jsfiddle to avoid side effects in IE7)
Steps to reproduce:
1. Save test case to local server.
2. Load in sIEve.
3. Reload page (or use auto-refresh)
Expected result:
No leaked elements detected.
Actual result:
The tt element is leaked along with a div (one of jQuery's support test elements)
Can also replicate this with the following:
- jquery-1.7.2
- jquery-1.7.1
- jquery-1.6.1 (with additional leaking support elements)
so this is not new to 1.8.
This issue may also effect IE8 but I am unable to confirm at present.
Attachments (0)
Change History (16)
Changed August 01, 2012 04:48PM UTC by comment:1
Changed August 01, 2012 05:02PM UTC by comment:2
The test case boils down to this:
$('<div/>').bind('click', function(){}); $('tt').bind('click', function(){});
You said the div
that was leaked was one of jQuery's support test elements, are you sure it's not the div from the test case? Does a test case with just one of the lines above leak as well? I can't try it myself at the moment.
Changed August 02, 2012 08:17AM UTC by comment:3
Replying to [comment:2 dmethvin]:
You said the div
that was leaked was one of jQuery's support test elements, are you sure it's not the div from the test case? Does a test case with just one of the lines above leak as well? I can't try it myself at the moment.
Retested the disconnected div changed to a code tag.
$('<code/>').bind('click', function(){}); $('tt').bind('click', function(){});
The following elements leak:
- the bound tt element
- the disconnected code element
- the html element
- a div element (a generated support element?)
Testing this with jquery1.7.2 leaks only the tt and code elements.
If I remove the line for the tt bind then I get 3 leaking elements (the tt is no longer leaked). If I remove the line for the code bind then there is no leak as would be expected.
Hope that clarifies things.
Changed August 21, 2012 01:50AM UTC by comment:4
status: | new → open |
---|
Okay, this needs more investigation.
Changed September 05, 2012 03:23AM UTC by comment:5
component: | unfiled → event |
---|
Changed October 15, 2012 05:43PM UTC by comment:6
priority: | undecided → low |
---|
Changed November 26, 2012 05:26AM UTC by comment:8
Good morning, is there any known workaround or patch for this problem?
I too have it, on ever page reload using latest jQuery and jQuery UI around 5-15 mb is leaked on IE7
Changed November 28, 2012 01:01PM UTC by comment:9
I created a wokraround in jQuery UI 1.8.19 by cleaning up the dpDiv variable in the Datepicker when the window is unloaded. Unbind it and set to null. Have not tested it on later versions.
This change removed the memory leak that occured by just including jQuery and jQuery UI on any page.
Changed January 11, 2013 01:53PM UTC by comment:10
Bear in mind the original case was unrelated to JqueryUI. Still unresolved.
Changed January 11, 2013 02:41PM UTC by comment:11
Still unresolved.
Yes, thats what the **(open bug)** means at the top of the page. If you have the time please take a look, we'd welcome the help. But please don't bump the ticket.
Changed January 18, 2013 07:32PM UTC by comment:12
Replying to [comment:9 peter.nystrom]:
I created a wokraround in jQuery UI 1.8.19 by cleaning up the dpDiv variable in the Datepicker when the window is unloaded. Unbind it and set to null.
Can you please provide the code for this?!
Changed January 18, 2013 08:59PM UTC by comment:13
_comment0: | I was able to fix this in IE6 by adding window unload event handling for undelegating the bound events that were creating circular reference. This change was added directly to the end of the function Datepicker(){...}. \ \ Clearing of the object references is just fluff, the real meat of the memory leak problem can be turned on and off by simply commenting in and out the line that does the undelegate. \ \ \ {{{ \ function Datepicker() { \ ... \ \ var self = this; \ $(window).unload(function(){ \ var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; \ //this line if the magic \ self.dpDiv.undelegate(selector, 'mouseover mouseout'); \ self._dialogInst = self.dpDiv = null; \ }); \ } \ }}} \ \ \ Sorry for pasting the entire jquery ui lib in the js window, but here is the fix in action: \ \ http://jsfiddle.net/ctoestreich/JFETB/ \ \ Cheers! → 1358543045917760 |
---|
I was able to fix this in IE6 by adding window unload event handling for undelegating the bound events that were creating circular reference. This change was added directly to the end of the function Datepicker(){...}.
Clearing of the object references is just fluff, the real meat of the memory leak problem can be turned on and off by simply commenting in and out the line that does the undelegate.
function Datepicker() { ... var self = this; $(window).unload(function(){ var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; //this line if the magic self.dpDiv.undelegate(selector, 'mouseover mouseout'); self._dialogInst = self.dpDiv = null; }); }
Sorry for pasting the entire jquery ui lib in the js window, but here is the fix in action:
http://jsfiddle.net/ctoestreich/JFETB/
As a bit of clarification, the method to add the module datepicker to jQuery is fired on page load and even when not specifically using datepickers on your page, simply the act of including the library would cause the problem as the orphaned object delegates were getting created on page load by:
$.datepicker = new Datepicker(); // singleton instance
This is called by the module on every load which in turn calls the object construction and adds the dpDiv and its event delegates that get orphaned due to circular references and being unattached to the dom in any way.
Cheers!
Changed January 24, 2013 12:52PM UTC by comment:14
My solution was similar to the one above, I created this function in the Datepicker that was called on window unload:
cleanup: function(target) { this.dpDiv.unbind(); this.dpDiv = null; },
Changed May 21, 2013 07:14AM UTC by comment:15
milestone: | None → 1.next |
---|
Changed March 16, 2014 05:05PM UTC by comment:16
resolution: | → patchwelcome |
---|---|
status: | open → closed |
We don't have the resources or inclination to fix this, and it's not a fatal error. Given the point we're at with IE6/7 support we're unlikely to land a fix unless it was only one or two lines, but if someone has such a fix we could consider it.
#12172 is a duplicate of this ticket.