IE Memory Leak – jQuery Fix
I suppose all of you have suffered all those terrible memory leaks in Internet Explorer.
Sometimes it’s bearable, but most of the time it’s not. I say enough is enough !
A couple of days ago, I had to create some web application with a very rich client side UI.
It worked like a charm in Google Chrome, Firefox… but IE7, after few dozens of nyroModal popups it just went dead.
Most of the styles are gone, JavaScript functions began to throw exceptions till it just stoped working, decided it can’t tolerate this kind of abuse any more and closed it self without any warning.
The first thing i did is to open Performance Monitor and what I see… every nyroModal popup i open cost me about 5Mb, so after a few clicks my IE7 virtual memory was about 789Mb. Terrifying, isn’t it ?

I’ve searched a bit and found the source of this problem was in one (of many) memory leaks IE7 proudly has – cleaning memory for removed HTML elements.
And now the fix.
1). Open your jQuery.js and find the next lines of code
jQuery.extend({
cache: {},
and add new function “discardElement”
jQuery.extend({
cache: {},
discardElement: function(element) {
var jqGCID = 'jqGarbageCollector';
var jqGC = document.getElementById(jqGCID);
if (!jqGC) {
jqGC = document.createElement('div');
jqGC.id = jqGCID;
jqGC.style.display = 'none';
document.body.appendChild(jqGC);
}
// place the element to the Garbage Collector
// and clear it's HTML contents
jqGC.appendChild(element);
jqGC.innerHTML = '';
},
2). Find the next lines of code in the opened jquery.js
remove: function( selector ) {
if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
// Prevent memory leaks
jQuery( "*", this ).add([this]).each(function(){
jQuery.event.remove(this);
jQuery.removeData(this);
});
if (this.parentNode)
this.parentNode.removeChild( this );
}
},
and replace “this.parentNode.removeChild( this );”
with “jQuery.discardElement(this);”
remove: function( selector ) {
if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
// Prevent memory leaks
jQuery( "*", this ).add([this]).each(function(){
jQuery.event.remove(this);
jQuery.removeData(this);
});
if (this.parentNode)
// this.parentNode.removeChild( this );
jQuery.discardElement(this);
}
},
That’s it, now you (and every plugin) can do $(‘element’).remove() without being worry IE will eat all of your memory.
A few posts you might find interesting:

One problem, this won’t work in an XHTML environment because there is no such thing as a
<DIV/>tag, only a<div/>tag. Please learn to use lowercase letters when usingdocument.createElement.@Elijah Grey
My bad, fixed it to lowercase “div”
Thanks for noticing that
@Elijah Grey
l***r
We sincerely appreciate your taking time to provide your comments and feedback, but Bad words will get filtered, and offensive comments will be removed.
I don’t think it matters at all. It will work with both DIV and div just fine.
By the way, if you check tagName property you will always get DIV
@maksik
You are probably right, but Elijah has a good point about XHTML and lowercase in general, though for JavaScript it makes no difference at all.
Excellent work on the plugin! I actually wrote a post about this very issue but thought it wasn’t a memory leak but rather IE lacked the ability to remove any dynamically generated DOM elements. I should have taken the time to write a plugin for this, but now it seems I can borrow on the mind of another brilliant mind!
A link to my post on this topic if you are interested – post a link to your post!
http://www.desmoinesmashups.com/blog/archive/2009/04/21/Cleanup-for-dynamically-generated-DOM-elements-in-IE.html
Hi, I have created a website, which uses jquery to update different parts on a webpage. everything is tabular data. I refresh parts of my webpage (tabs) without leaving the page dynamically (every 2 sec). if i keep it open for a long time in IE6/7/8 it grows around 1.4GB in main memory. I have modifed my js files as you said here. but I dont know how to call/use $(’element’).remove() when when to call. can you show me an simple example?
waiting for reply…
Thanks a lot
-Mathiev
Just an update for above Question, I ask server to send me xml files which i supply to jquery grids.
jQuery(“#Log”).jqGrid({
url: ‘LogFile.xml’,
datatype: ‘xml’,
mtype: ‘GET’,
xmlReader: {
root: “Rows”,
row: “Row”,
repeatitems: false,
id: “asin”
},
colNames: ['Log Entries'],
colModel: [{ name: "LogEntry", index: 'LogEntry', width: 1300, sortable: false}],
imgpath: ‘jsFiles/theme/basicGrid/images’,
loadui: ‘disable’,
height: ‘100%’,
caption: ‘Log View’
});
Is this problem fixed in IE8?
@Elijah Grey Please learn to use lowercase letters when using document.createElement?
Please learn that where to put the slash in the closing tags.
@Keith Petersen
When i tested it (on beta) the bug was still there.
@mathiev
Actually i don’t think jqGrid is using $(‘element’).remove() before updating the content. Try to find the exact place where the plugin updating the content and just use :
var jqGridContainer = document.getElementById(‘#yourjqGridContainerID’);
jqGridContainer .innerHTML = ”;
This is the place in my code where I am reloading the grid data.
var l;
var ltimeout = 2000;
function RefreshLogGrid()
{
jQuery(“#Log”).trigger(“reloadGrid”);
jQuery(“#Log”).setGridHeight(‘auto’);
l = setTimeout(“RefreshLogGrid()”, ltimeout);
}
where ltimeout (2sec) is refresh time and this is grid location with ID is as follows
it is updating data correctly. but where should i use
var jqGridContainer = document.getElementById(“log123″);
jqGridContainer .innerHTML = ”;
if i use like this
var l;
var ltimeout = 2000;
function RefreshLogGrid()
{
var jqGridContainer = document.getElementById(“log123″);
jqGridContainer .innerHTML = ”;
jQuery(“#Log”).trigger(“reloadGrid”);
jQuery(“#Log”).setGridHeight(‘auto’);
l = setTimeout(“RefreshLogGrid()”, ltimeout);
}
I dont see any entry in my jqGrid
any idea? how to fix this memory leak bug.
- Mathiev.
@mathiev
What is “log123″, i see that the container’s ID is ‘Log’ (“#Log”)
What exactly the code of “reloadGrid” ?
log123 is id, where #Log is grid_id.
and jQuery(”#Log”).trigger(”reloadGrid”);
uses standard lib downloaded from JQ
jquery-1.3.2.min.js
log123 is div id
From what i understand you are cleaning the ‘log123′ which contains the grid.
Clean the grid (‘#log’) instead, otherwise you are removing the ‘#Log’ element.
Hi Xander,
Actually I was looking for the solution and I found 1 webpage
http://dev.jquery.com/ticket/1233
which explains same problem as me. but I am not sure how to call
“GarbageCollect?(); ” from my jscript which will release all IE memory (like clicking refresh button)
@mathiev
Look at my previous reply, as i mentioned – you are probably cleaning the wrong div
Its not working either. If I do that I am getting following error message
this.parentNode is null
@mathiev
It’s a bit tricky to solve a problem without seeing the whole picture.
this.parentNode will throw exception if you are passing an empty (or non-existent) selector.
Just Debug the code and check what is passed to the function
Hi Xander,
Thanks very much for this post, it is quite helpful. Have you discussed any of this with the jQ devs? Is a fix destined for “stock” jQ?
Thanks,
Jim
@Jim
I’m glad to hear you find it useful and helpful.
No, I didn’t discussed about it with jQuery Team, but you right – I should and will.
@Jim
Opened a new ticket at jQuery Bug Tracker.
Ticket #4929
Thanks Xander
Xander,
I’ve applied your patch to some jQuery which is using jQuery UI’s dialog and leaks memory in IE7. Opening a dialog raises the memory usage, and closing it never returns that memory. So after several dialogs are opened and closed, IE is killing the machine again. Sadly, your patch made no difference. I looked at the source of the dialog code and it does use .remove(). Have you used your patch successfully with UI’s dialog?
I’ll keep poking around.
Thanks,
Jim
@Jim
No, not with UI, but as long it uses jQuery .remove() it should work.
Please make sure you are referencing the modified jQuery.js and not the minified or packed version.
Thanks for the fast reply. I am definitely referencing the proper file as I adding debugging into it when I saw it wasn’t working. The methods are being entered, but IE is still chomping memory.
We’ll keep digging on our end as perhaps it’s something which we’re putting into the dialog which is exacerbating the issue.
Jim
Hello Xander,
At the risk of being a pest, I’d like to show you a test a came up with for pure jQuery UI dialogs.
At http://jaaulde.com/test_bed/ie_mem_leak/ you’ll see a ‘patched’ and ‘unpatched’ directory. They contain the same code, except that one is pointing at a version of jQuery with your fix patched in, the other is not.
As far as I can tell, in both versions, IE is never letting go of even the small amount of memory which a very simple dialog requires. However, I am not the best at measuring performance like this, so maybe I am missing something. With that in mind, do you mind taking a look at my link and seeing if you think it is working?
Thanks very much,
Jim
@Jim
Hi, i’ve checked your files and it seems that the memory leak you are dealing with is not related to the one i’m trying to solve.
This one leaks even in Google Chrome…
As i mentioned before this is a solution for one (of many) memory leaks IE7 proudly has..
I think the cause for this specific leak is what called circular references (in jQuery UI) and i’m sorry but i can’t help you with this one…
Thanks very much, Xander. I appreciate your time.
Great article that aggregates fixes to all the various jQuery memory leaks dealing with UpdatePanel refreshes at http://www.quattrosource.com/2009/07/fixing-jquery-memory-leaks-in-asp-net/
Thanks. Great article.
We’re finding we get memory leaks simply by setting elements via the $(“#id#).text() function so hopefully that’ll help us out!
Hi Xander,
I appreciate your post as over net I browsed and have not found any fix. Everyone talks about the bug but only few talk about the fix.
My request to you is that, since for my web application I am not using JQuery so could you please provide me or give me idea how to implement the same GC logic in plain JavaScript so that I can out it to my webpage(s) and get rid on IE memory leak problem.
Regards,
Soumen
India-Hyderabad
@Soumen
The “discardElement” function is not using jQuery, so just replace the “discardElement: function(element)” with “function discardElement(element)” if you want it to be standalone.
Has this issue been taken care of in jquery 1.4? …something like a patch (similar to yours) to that effect