Opened 10 years ago

Closed 7 years ago

#4566 closed bug (fixed)

Including ui.datepicker.js causes a memory leak in IE6

Reported by: ncj102 Owned by:
Priority: major Milestone: 1.7.2
Component: ui.datepicker Version: 1.7.1
Keywords: ie6 memory leak datepicker Cc:
Blocked by: Blocking:

Description

I used IE 6.0.2800 on Windows 2000 SP1.

I am using the jQuery nightly build from May 28. I also included ui.core and ui.dialog at r2623.

To reproduce: Create a page that does something simple, like:

	<div id="box">hi</div>
	<script type="text/javascript" language="javascript">
	$(document).ready(function()
	{
		var dialog = $('#box').dialog();
	});
	</script>

Notice that the datepicker is not being used. Now browse to the page and away. In my case, I find 12 memory leaks (as reported in #4565). Now add the script "ui.datepicker.js", but make no other changes. Browse to the page and away, again. You'll find that there is one more memory leak than there was without the datepicker library. In my case I find 13 leaks.

sIEve shows the additional leaking element as a div with the id "ui-datepicker-div".

Change History (13)

comment:1 Changed 10 years ago by Jörn Zaefferer

Milestone: TBD1.8

comment:2 Changed 10 years ago by kbwood

See also #4644 - in 1.7.2.

comment:3 Changed 10 years ago by GazQuest

In my jQuery UI tests I have been experiencing memory leaks in IE 7 caused by the repeated use of filter: in the theme css which is used to apply a transparent overlay on modal dialogs or to create shadow effects such as :

.ui-datepicker-cover { ... filter: mask(); /*must have*/}
.ui-widget-overlay { ... filter:Alpha(Opacity=30);}
.ui-widget-shadow { ... filter:Alpha(Opacity=30);}

IE has a known bug where filter: will claim memory each time it is used. The memory is only released when the page is navigated away from or refreshed which is a big problem for single-page dynamic ajax applications

There is a workaround for this which stops the memory leak; edit the theme's css file and remove all filter: rules. In the case of the .ui-widget-overlay rule, which dims the background page during a modal dialog, I replaced the filter: with this :

background: transparent url(images/GridLattice.gif) top left repeat;

The grid lattice gif is just a gif with alternative coloured pixels and transparent pixels. It's ugly but does the job without memory leaks.

I checked out extJS which uses filter: in the same way for modal dialogs but it doesn't suffer from increasing memory leaks. This is because the overlay div is always present so filter: is only instantiated once. You do get a memory hit on the first dialog but no more leaks after that because the same filter: element is used for all subsequent modal dialogs.

I suspect that jQuery UI creates new dom elements each time it needs a filter: which explains why the memory usage rises continuously on the same page with use.

A possible fix would be to do what extJS does and leave a filter: dom element ever present on the screen and just show/hide as necessary, this would work for modal dialogs at least.

For now I'm happy with the grid lattice gif fix and it's a relief to see memory usage stable when I open new dialogs as it was making me wonder if jQuery UI is ready for the kind of app I'm writing. I'd already had to rule out extJS because it is too slow on the typical target machines my users will be using, and I was running out of options other than self-build!

I don't know if this has been reported before but if not then it could explain some of the other IE memory leaks that have been reported. All it takes is a filter:

Gaz

comment:4 Changed 10 years ago by GazQuest

Nope I take half of that back. The above works if you keep the same modal dialog open and keep re-opening it. But for every new dialog I open I get a 200k hit that is never released. This has nothing to do with filter:. I destroy everything to do with the dialog

I've come up with a workaround which is to have a pool of divs that are specifically for dialogs. I have an array of [false, false, false etc...] to start with which means none of the div are dialogs yet. When I request a dialog I check if there are any uninitialized divs and dialog( oConfig) them. If there are no uninitialized divs then I check each dialog( 'isOpen') == false and use closed dialogs with the new dialog

If there are no divs left I can either say "Too many windows open" or dynamically add another to the pool of dialog divs. Seems to work ok in my preliminary testing but I've yet to test with dynamic data being added to the dialogs

You get a memory hit for each dialog but at least it is capped to how many dialog divs I have. So effectively it looks like you need a dialog manager to work with multiple dialogs in a long-life single-page app otherwise you get memory leaks

comment:7 Changed 10 years ago by tebulin

GazQuest notes that the issue originates from a used CSS themen with IE filter statements.

I just wanted to note that this does not seem the soley problem, as we expierience still heavy leaks in IE even after removing all of them.

So besides the depicted filter issue, further leaks seem to exist.

comment:8 Changed 10 years ago by asoft

For those waiting on the IE6 + Memory leak fix, from what I can tell it can be drastically reduced / eliminated by adding in the following lines (based on full ui.datepicker.js v1.7.2) to the end of function "_destroyDatepicker":


$target.unbind('setData.setData.datepicker').unbind('getData.setData.datepicker');
this._lastInput = null;


The first line should fix the issue where simply 'including' the datepicker results in a memory increase. This is due to (for whatever reason) the anonymously bound functions not being 'unbound'.

The second line removes a circular reference (if applicable) that occurs due to datepickers internal workings.

Both lines are not a standalone fix. You need to make sure in whatever script is instantiating the datepickers that it will also 'destroy' them when they are no longer needed:


$(window).unload(function() {

$('<your date picker element selector(s) here>').datepicker('destroy');

});


*note: would have posted on SO but didn't have an openid account. might get around to it. eventually...

comment:9 in reply to:  8 Changed 10 years ago by asoft

Replying to asoft:

$target.unbind('setData.setData.datepicker').unbind('getData.setData.datepicker');

proof reading fail. that should be:

$target.unbind('setData.datepicker').unbind('getData.datepicker');

comment:10 Changed 9 years ago by Scott González

Also see #4906.

comment:11 Changed 8 years ago by Scott González

#7450 is a duplicate of this ticket.

comment:12 Changed 8 years ago by inspiraller

Ok, this is hilarious. I have been trying to figure out why using jquery ui dialog suddenly causes IE to go from 20kb to 350kb of memory. The reason is the css. Using @ symbols truly F IE. Also, if you have a lot of css, it screws it up too.

comment:13 Changed 8 years ago by Scott González

#7802 is a duplicate of this ticket.

comment:14 Changed 7 years ago by Scott González

Milestone: 1.9.01.11.0

comment:15 Changed 7 years ago by mikesherov

Milestone: 1.11.01.7.2
Resolution: fixed
Status: newclosed

jQuery UI stopped using @ symbols in css in 1.7.2 Please feel free to file a new bug if you still believe there's a memory leak.

Note: See TracTickets for help on using tickets.