Skip to main content

Search and Top Navigation

#4188 closed bug (patcheswelcome)

Opened February 19, 2009 12:22PM UTC

Closed April 23, 2014 04:13PM UTC

Last modified May 06, 2014 12:06PM UTC

Widget: Huge memory leaks for all widgets in IE

Reported by: paul Owned by:
Priority: major Milestone: 2.0.0
Component: ui.widget Version: 1.6rc6
Keywords: Cc:
Blocked by: Blocking:
Description

We have huge memory leaks in IE 6, even with the simpliest plugins, so I believe it's related to the widget factory. Tested with Drip 0.5 and /tests/visual/draggable/default.html

Attachments (1)
Change History (52)

Changed February 19, 2009 12:22PM UTC by paul comment:1

owner: → paul
status: newaccepted

Changed February 19, 2009 12:50PM UTC by paul comment:2

First find: Does not happen for progressbar widget

Changed February 19, 2009 12:54PM UTC by paul comment:3

description: We have huge memory leaks in all version of Internet Explorer, even with the simpliest plugins, so I believe it's related to the widget factory. Tested with Drip 0.5 and /tests/visual/draggable/default.htmlWe have huge memory leaks in IE 6, even with the simpliest plugins, so I believe it's related to the widget factory. Tested with Drip 0.5 and /tests/visual/draggable/default.html
summary: Huge memory leaks for all widgets in all version of IEHuge memory leaks for all widgets in IE6

Changed February 19, 2009 01:08PM UTC by paul comment:4

Ok, the issue seems to be around the calls to bind() in the widget constructor from line 270-283 in ui.core.js.

Changed February 19, 2009 02:56PM UTC by paul comment:5

After further debugging, it seems that the memory leaks are directly related to any of the following events: setData, getData, remove. They just need to be bound - they don't even have to be triggered, and can just include an anonymous function.

Changed February 23, 2009 01:24PM UTC by paul comment:6

owner: paul
status: acceptedassigned

Changed February 24, 2009 09:59AM UTC by rdworth comment:7

priority: blockercritical

Changed February 25, 2009 03:42AM UTC by dmuir comment:8

Do you mean the binding in this block here?

Is it happening

this.element = $(element)
			.bind('setData.' + name, function(event, key, value) {
				if (event.target == element) {
					return self._setData(key, value);
				}
			})
			.bind('getData.' + name, function(event, key) {
				if (event.target == element) {
					return self._getData(key);
				}
			})
			.bind('remove', function() {
				return self.destroy();
			});

After a quick scan of the code, the only difference with these binds and the others being done is that these are custom event handlers. Would this be a bug with jQuery's custom event handlers?

Changed February 25, 2009 04:08AM UTC by dmuir comment:9

Changed February 25, 2009 04:38AM UTC by scottgonzalez comment:10

All namespaced events leak memory in jQuery 1.3.x. I've created a ticket in core's Trac.

Changed March 08, 2009 02:42PM UTC by rdworth comment:11

milestone: 1.71.8

Changed May 08, 2009 11:07AM UTC by jzaefferer comment:12

Looks like Brandon found a fix, therefore this ticket depends on jQuery's 1.3.3 release.

Changed May 14, 2009 07:33PM UTC by dwradcliffe comment:13

Replying to [comment:12 joern.zaefferer]:

Looks like Brandon found a fix, therefore this ticket depends on jQuery's 1.3.3 release.

I am using the most recent build of jQuery (r6348) and the problem is still here. Widgets such as dialogs, tabs, and datepicker are leaking. They only seem to leak when *other* *unrelated* html elements are removed from the HTML DOM.

Changed May 27, 2009 09:43PM UTC by ivarsv comment:14

the problem is with the event bindings as mentioned above. If the anonymous functions are replaced by normal functions the leaks seem to disappear. Here is a simple test to create 5 memory leaks (tested in sieve):

<div id="leak"></div>
<script type="text/javascript">//<![CDATA[
$.widget('ui.test1', { 
    _init : function() { 
        $(document.createElement('div'))
            .appendTo(this.element)
            .text('memleak')
            .test2(); 
    }
}); 

$.widget('ui.test2', { }); 
$('#leak').test1().remove(); 
//]]>
</script>

Apply the patch attached and test again. the memory leaks should be fixed.

Changed August 06, 2009 05:15PM UTC by jzaefferer comment:15

All three of those bindings will be removed in the new widget factory (http://jquery-ui.googlecode.com/svn/branches/dev/widget-factory/), so updating to that should fix this ticket, too.

We'll probably add some migration-code to make it even easier to use the new widget factory; currently a few minor changes to existing widgets are necessary.

Changed December 04, 2009 09:28AM UTC by vitrilo comment:16

I confirm that this bug exist for IE8 (jQuery UI 1.7.1).

These tests may be helpful (Tested on IE8).

<script>
	function doJQueryLeak(){
	    for(var i=0;i<100;i++){ _createJQueryLeak();}
	}
	function doNoJQueryLeak(){
	    for(var i=0;i<100;i++){ _createNoJQueryLeak();}
	}
	function doNoCoreIeEventLeak(){
	    for(var i=0;i<10000;i++){ _createNoLeakEvent(); };
	}
	function doCoreIeEventLeak(){
	   for(var i=0;i<10000;i++){ _createLeakEvent(); };
	}
        //private
	function _createJQueryLeak(){
	    var item = $("<span>Damn</span>");
	    //can be any jQuery UI widget
	    item.draggable({ helper: 'clone', revert: 'invalid', zIndex: 2000, addClasses: false});
	    item.draggable('destroy');
	    item.unbind();
	}
	function _createNoJQueryLeak(){
	    var item = $("<span>Damn</span>");
	}
	function _createNoLeakEvent(){
	    var elm = document.createElement("DIV");
	    elm.innerHTML = "Some Div";
	    var myhandler = function(){
		 elm.yy = 5;
	    }
	    elm.attachEvent("onclick", myhandler);
	    elm.detachEvent("onclick", myhandler);
	}
	function _createLeakEvent(){
	    var elm = document.createElement("DIV");
	    elm.innerHTML = "Some Div";
	    var myhandler = function(){
		 elm.yy = 5;
	    }
	    elm.attachEvent("onSetData", myhandler);
	    elm.detachEvent("onSetData", myhandler);
	}
    </script>

Changed January 28, 2010 02:02AM UTC by scottgonzalez comment:17

milestone: 1.81.next

Changed July 30, 2010 10:17AM UTC by jzaefferer comment:18

Its been a while... did jQuery 1.4 or jQuery UI 1.8 make any difference?

The related core ticket got closed a year ago: http://dev.jquery.com/ticket/4241

Changed October 19, 2010 03:51PM UTC by scottgonzalez comment:19

priority: criticalmajor

Changed October 28, 2010 06:20PM UTC by scottgonzalez comment:20

component: ui.coreui.widget

Changed February 10, 2011 09:04PM UTC by jihohan comment:21

In 1.8.9, there is a memory leak in ui.widget.js. I created a test case here http://jsfiddle.net/hEnFt/.

The gist of it is here:

<div id="container">
    <div id="inner">inner div</div>
</div>
<hr/>
<a href="#" id="clear">clear</a>
<script type="text/javascript">
    $("#inner").test();
    
    $("#clear").click(function(event) {
    event.preventDefault();
    
    $("#inner").test("destroy");
    
    $("#container").html("");
    });
</script>

Basically, on click of the link, I empty the container div. But before that I call destroy on the widget.

I can see that there is a single leak in sIEve. I can trace the cause of the leak to this call in _createWidget:

var self = this;
this.element.bind( "remove." + this.widgetName, function() {
	self.destroy();
});

If I comment out the bind, the leak goes away. I tested separately for binding/unbinding of custom events, with and without namespace, jquery does not seem to have an issue. It must be a circular reference not being cleaned up in the widget code but can't figure it out for myself.

Changed February 11, 2011 01:33AM UTC by scottgonzalez comment:22

status: assignedopen

jihohan: thanks for looking into this. I've recently changed that bit of code, can you retest against master and see if the leak still exists?

Changed February 11, 2011 02:46PM UTC by jihohan comment:23

I still see a leak with the latest unfortunately.

Changed February 11, 2011 08:23PM UTC by jihohan comment:24

This is an additional observation regarding my code sample at http://jsfiddle.net/hEnFt/.

If I create another div outside of #container, and use the widget on it, then that starts leaking too.

<div id="container"><div id="inner"></div></div>
<hr/>
<div id="unrelated">

If I create the widget on both #inner and #unrelated and then I take out the #inner from the document, both #inner and #unrelated leak. So it seems if I remove any widget from the document, all widgets leak.

This happens on both 1.8.9 and the latest.

Changed February 11, 2011 09:07PM UTC by jihohan comment:25

One more observation is that if you remove the bind call for "remove" event from _createWidget() and do bind outside the widget, then there is no leak.

In other words, you do this:

$("#inner").test()
    .bind("remove.test", function() {});

Another interesting thing I noticed, as I dug into jquery 1.4.4, is that I found the following block of code in jQuery.event.add:

if ( elem.addEventListener ) {
	elem.addEventListener( type, eventHandle, false );
} else if ( elem.attachEvent ) {
	elem.attachEvent( "on" + type, eventHandle );
	//elem.detachEvent( "on" + type, eventHandle ); // added by me
}

So, if I comment out attachEvent call, there is no leak, and no surprise there.

But if I uncomment the following line and detach the handler right away, it leaks. So the leak isn't coming from not unbinding or not cleaning up after ourselves. I believe it's some type of closure related leak that gets created at the point of attachEvent. I mean I've created jquery plugins (not jquery.ui) with event bindings but I've managed to create them leak free but none of my plugins have complex closures that jquery.ui does.

Finally, there is also no leak to speak of, until I remove a widget element from the document. If I never remove any elements, so that there is no ajax-y DOM manipulations stuff and if there are only whole page loads, there is no leak.

For example, I tested the leak patterns from Understanding and Solving Internet Explorer Leak Patterns, and I could not see any memory leaks because none of them involve removing an element from the document. Perhaps those particular leaks were fixed by service packs, seeing as that document is pretty old, circa 2005.

Changed February 14, 2011 02:34PM UTC by jihohan comment:26

Testing with release 1.5 of jQuery, the number of leaks shown in sIEve for the test sample increased from 1 to 4. I'm not exactly sure what that number is supposed to mean but it can't be good.

Changed August 12, 2011 12:57PM UTC by scottgonzalez comment:27

sIEve is telling me that there are no leaks, even for older versions.

Changed August 24, 2011 08:48PM UTC by garyz comment:28

I still see leaks for IE7. Put http://jsbin.com/ekefov in sIEve and every refresh leaks 15 dom elements.

For the same page, sIEve report no leaks on IE8.

Changed August 24, 2011 09:09PM UTC by rdworth comment:29

Replying to [comment:32 garyz]:

I still see leaks for IE7. Put http://jsbin.com/ekefov in sIEve and every refresh leaks 15 dom elements. For the same page, sIEve report no leaks on IE8.

This ticket is for memory leaks in all widgets because all widgets use $.ui.widget core, so tests for this ticket must use little more than $.ui.widget. For examples see earlier comments, such as http://bugs.jqueryui.com/ticket/4188#comment:25 .

Your test shows a leak in Dialog, so it should be added to #4565

Changed August 24, 2011 10:07PM UTC by garyz comment:30

Replying to [comment:33 rdworth]:

Replying to [comment:32 garyz]: > I still see leaks for IE7. Put http://jsbin.com/ekefov in sIEve and every refresh leaks 15 dom elements. > > For the same page, sIEve report no leaks on IE8. This ticket is for memory leaks in all widgets because all widgets use $.ui.widget core, so tests for this ticket must use little more than $.ui.widget. For examples see earlier comments, such as http://bugs.jqueryui.com/ticket/4188#comment:25 . Your test shows a leak in Dialog, so it should be added to #4565

Sorry, should have read all the comments. I took out the dialog widget and replaced it with an empty widget. still shows 1 leak for IE7, okay for IE8. http://jsbin.com/ekefov/2/

Changed January 31, 2012 08:33PM UTC by scottgonzalez comment:31

#7808 is a duplicate of this ticket.

Changed January 31, 2012 08:33PM UTC by scottgonzalez comment:32

#7666 is a duplicate of this ticket.

Changed June 30, 2012 03:02PM UTC by jmstreet comment:33

_comment0: First post guys, but we had massive memory leaks with jQuery UI in IE6 recently. \ We were using release 1.8.9 and found that dialog boxes would leak 6-10meg of memory and roughly ten custom event handlers (binds) per page leaked 3-4meg. None of this memory was released on page submit. \ \ We upgraded to a custom jQuery UI build of 1.8.21 (including accordians and dialogs) and it works like a charm. \ 6-10meg of memory is still being used for dialogs, but is released on page submit, and no memory is leaking relating to custom event handling. \ \ Phew! Cheers guys.1341068628556935
_comment1: First post guys, but we had massive memory leaks with jQuery UI in IE6 recently. \ We were using release 1.8.9 and found that dialog boxes would leak 6-10meg of memory and roughly ten custom event handlers (binds) per page leaked 3-4meg. None of this memory was released on page submit. \ \ We upgraded to a custom jQuery UI build of 1.8.21 (which included accordians and dialogs only) and it works like a charm. \ 6-10meg of memory is still being used for dialogs, but is released on page submit, and no memory is leaking relating to custom event handling. \ \ Phew! Cheers guys.1341076322311341

First post guys, but we had massive memory leaks with jQuery UI in IE6 recently.

We were using release 1.8.9 and found that dialog boxes would leak 6-10meg of memory.

We also found that roughly ten custom event handlers (which used the method "bind") leaked 3-4meg per page. None of this memory was released on page submit.

We upgraded to a custom jQuery UI build of 1.8.21 (which included accordians, dialogs, and the core only) and it now works like a charm: 6-10meg of memory is still being used for dialogs, but it is released on page submit, and no memory is leaking relating to custom event handling.

Phew! Cheers guys.

Changed June 30, 2012 04:30PM UTC by scottgonzalez comment:34

Is anyone else still seeing a leak? If not, I'll close this as fixed in a few days.

Changed July 09, 2012 01:01PM UTC by scottgonzalez comment:35

I'm going to close this on Friday unless someone else can confirm or deny jmstreet's claim.

Changed July 13, 2012 05:20AM UTC by NikGovorov comment:36

_comment0: Issue from ticket #7808: http://jsfiddle.net/Bq7tJ/3/ is still reproducible. Why have you closed the original issue and don't have applied the pull request: https://github.com/jquery/jquery-ui/pull/513?1342157092431298

Issue from ticket #7808: http://jsfiddle.net/Bq7tJ/3/ is still reproducible. Why have you closed the original issue and don't have accepted the pull request: https://github.com/jquery/jquery-ui/pull/513?

Changed July 13, 2012 11:51AM UTC by scottgonzalez comment:37

@NikGovorov That ticket was closed as a duplicate. I didn't accept the pull request because it completely breaks widgets.

Changed July 14, 2012 01:09AM UTC by NikGovorov comment:38

Replying to [comment:41 scott.gonzalez]:

@NikGovorov That ticket was closed as a duplicate. I didn't accept the pull request because it completely breaks widgets.

Clear. Anyway all widgets leak in ie 7 and ie 8(didn't try in ie 6) with 1.8.21, even if create own simple(empty) widget.

Changed July 15, 2012 11:44PM UTC by NikGovorov comment:39

_comment0: Replying to [comment:42 NikGovorov]: \ > Replying to [comment:41 scott.gonzalez]: \ > > @NikGovorov That ticket was closed as a duplicate. I didn't accept the pull request because it completely breaks widgets. \ > Clear. Anyway all widgets leak in ie 7 and ie 8(didn't try in ie 6) with 1.8.21, even if create own simple(empty) widget. \ \ The same for the current version(master branch).1342395913407240

Replying to [comment:42 NikGovorov]:

Replying to [comment:41 scott.gonzalez]: > @NikGovorov That ticket was closed as a duplicate. I didn't accept the pull request because it completely breaks widgets. Clear. Anyway all widgets leak in ie 7 and ie 8(didn't try in ie 6) with 1.8.21, even if create own simple(empty) widget.

The same for the current version(master branch).

http://jsfiddle.net/8nbN2/

Changed July 23, 2012 10:13AM UTC by jh.huddle comment:40

I'm seeing @jmstreet's issue as well.

On IE7 using sIEve.

With a single jQuery bind call I get a leak on the bound element. Just the presence of jQuery.ui and the bind call triggers the problem. There are no widget instances on the page.

A test case is at: http://jsfiddle.net/johnhunter/2LLD9/ (running this locally to avoid effects from jsfiddle).

When the page is reloaded the bound element is leaked. Loading the test page in sIEve and activating 'auto-refresh' shows a leak for the bound element on each page reload.

Can replicate with jQuery UI 1.8.21, 19, 18 and jQuery 1.7.2 - 1.6.2.

Changed July 23, 2012 11:07AM UTC by NikGovorov comment:41

Replying to [comment:43 NikGovorov]:

Replying to [comment:42 NikGovorov]: > Replying to [comment:41 scott.gonzalez]: > > @NikGovorov That ticket was closed as a duplicate. I didn't accept the pull request because it completely breaks widgets. > Clear. Anyway all widgets leak in ie 7 and ie 8(didn't try in ie 6) with 1.8.21, even if create own simple(empty) widget. The same for the current version(master branch). http://jsfiddle.net/8nbN2/

The issue disappears if use jquery 1.8.

Changed July 24, 2012 07:38AM UTC by stumblor comment:42

_comment0: I can confirm that, based on the original test: \ http://jsfiddle.net/Ds7Jv/8/ \ \ However there is a bigger leak that occurs if the page is reloaded: \ http://jsfiddle.net/Ds7Jv/14/ \ 1343115601137973
_comment1: I can confirm that, based on the original test: \ http://jsfiddle.net/Ds7Jv/8/ \ \ However there is a bigger leak that occurs if the page is reloaded (using Jquery 1.8b3): \ http://jsfiddle.net/Ds7Jv/14/1343116537467119

I can confirm that, based on the original test:

http://jsfiddle.net/Ds7Jv/8/

However there is a bigger leak that occurs if the page is reloaded (using Jquery 1.8b2):

http://jsfiddle.net/Ds7Jv/14/

Changed July 24, 2012 10:46AM UTC by stumblor comment:43

Replying to [comment:46 stumblor]:

I can confirm that, based on the original test: http://jsfiddle.net/Ds7Jv/8/ However there is a bigger leak that occurs if the page is reloaded (using Jquery 1.8b2): http://jsfiddle.net/Ds7Jv/14/

Further testing - No leak in

JQuery 1.4.4

JQuery UI 1.8.7

http://jsfiddle.net/Ds7Jv/17/

Changed August 01, 2012 11:56AM UTC by jh.huddle comment:44

Replying to [comment:44 jh.huddle]:

On IE7 using sIEve. With a single jQuery bind call I get a leak on the bound element. Just the presence of jQuery.ui and the bind call triggers the problem. There are no widget instances on the page.

This is due to a jQuery bug http://bugs.jquery.com/ticket/12171. Creating a disconnected element and then binding an event handler to it causes all subsequent bind calls to leak their elements. This is triggered in the Datepicker where the bindHover function binds event handlers to dpDiv which is a detached element.

Changed October 03, 2012 03:40PM UTC by scottgonzalez comment:45

milestone: 1.next2.0.0

Changed October 16, 2012 02:18PM UTC by bavanyo comment:46

#4565 is a duplicate of this ticket.

Changed November 09, 2012 07:22PM UTC by tj.vantoll comment:47

summary: Huge memory leaks for all widgets in IE6Widget: Huge memory leaks for all widgets in IE

Dropping the "6" from the title since support is being dropped in 1.10. There is talk in this ticket of leaks in IE7 and IE8 that should be verified with 1.9.

Changed January 31, 2013 02:09PM UTC by scottgonzalez comment:48

Can anyone reproduce this with jQuery 1.9.0 and jQuery UI 1.10.0?

Changed November 28, 2013 02:19PM UTC by scottgonzalez comment:49

#9682 is a duplicate of this ticket.

Changed December 23, 2013 04:24PM UTC by mtc comment:50

I can reproduce this with jQuery 1.9.1, jQueryUI 1.10.3 on IE7 using the jquery UI demo site. Memory usage keeps climbing when I switch between the different widget pages.

Changed April 23, 2014 04:13PM UTC by scottgonzalez comment:51

resolution: → patcheswelcome
status: openclosed

We haven't been able to track this down and fix it, so this has just been sitting. At this point, we're just going to close this ticket, but we'd gladly accept a patch if someone can figure out what's causing the leak.

Changed May 06, 2014 12:06PM UTC by scottgonzalez comment:52

#10030 is a duplicate of this ticket.