Opened 12 years ago

Closed 8 years ago

#5382 closed defect (wontfix)

Memory leak on new() and destroy() widget

Reported by: guest Owned by: bill
Priority: blocker Milestone: future
Component: Dijit Version: 1.0
Keywords: Cc:
Blocked By: Blocking:

Description (last modified by bill)

Just create a widget,and then destroy it.This will causes memory leak. I use procexp.exehttp://www.microsoft.com/technet/sysinternals/utilities/processexplorer.mspx to monitor the memory usage,and it's increasing. My OS is Windows XP and this memory leak occur in IE6 and IE7 both.

graph from sIeve

Attachments (6)

test.html (902 bytes) - added by guest 12 years ago.
test page.
Memo.js (348 bytes) - added by guest 12 years ago.
the widget written for test.
memory usage graph.rar (43.9 KB) - added by guest 12 years ago.
memory usage graph(by procexp.exe)
memory.png (4.8 KB) - added by bill 12 years ago.
graph from sIeve
iehashbug.html (446 bytes) - added by haysmark 11 years ago.
Test demonstrating IE hash bug, which causes IE to fail to release the memory even on delete and CollectGarbage?().
iebug_graph.JPG (22.6 KB) - added by haysmark 11 years ago.
Result of running IE hash bug test in sieve.

Download all attachments as: .zip

Change History (18)

Changed 12 years ago by guest

Attachment: test.html added

test page.

Changed 12 years ago by guest

Attachment: Memo.js added

the widget written for test.

comment:1 Changed 12 years ago by bill

Milestone: 1.1
Owner: set to bill

Note: related to #4641 but this is failing on a trivial widget, so easier test case then using Menu. I'll try to address for 1.1.

comment:2 Changed 12 years ago by Adam Peller

while it's entirely possible we have a memory leak here, I'm not sure increasing process size proves it. There's GC running and caches, so it's not always obvious. Does this growth continue linearly?

Changed 12 years ago by guest

Attachment: memory usage graph.rar added

memory usage graph(by procexp.exe)

comment:3 Changed 12 years ago by guest

yeah,the memory usage is ebb and flow,but it's increasing obviously.I upload two memory usage graphs.One is near 5 minutes after IE browser running,and the other is near 10 minutes.The memory is 20M first,and it's 24M 5 minutes later,and 30M 10 minutes later.

comment:4 Changed 12 years ago by bill

Milestone: 1.11.2

comment:5 Changed 12 years ago by Douglas Hays

Priority: normalhigh

can this be moved back into 1.1?

comment:6 Changed 12 years ago by Adam Peller

I think it's out of 1.1 unless there's a patch to look at. Perhaps we can consider for 1.1.1 also with a patch.

Changed 12 years ago by bill

Attachment: memory.png added

graph from sIeve

comment:7 Changed 12 years ago by bill

Description: modified (diff)

Yup, I see the memory increasing, although sIeve says there are no DOM leaks... I guess it's a different sort of problem.

comment:8 Changed 11 years ago by bill

Milestone: 1.2future

Changed 11 years ago by haysmark

Attachment: iehashbug.html added

Test demonstrating IE hash bug, which causes IE to fail to release the memory even on delete and CollectGarbage?().

Changed 11 years ago by haysmark

Attachment: iebug_graph.JPG added

Result of running IE hash bug test in sieve.

comment:9 Changed 11 years ago by haysmark

It's not a Dojo bug; it's an IE bug with deleting from hashes.

I've attached a very simple test with zero Dojo demonstrating this bug. Basically, delete from a hash does not clear the memory in IE. Even calling CollectGarbage?() after the delete does not clean it up! This bug affects many key Dojo and Dijit components, like dojo.connect and dijit.registry (dijit/manager.js), since they keep a hash for things like widget id.

For example, dijit/manager.js has some bugged code:

remove: function(/*String*/ id){
	delete this._hash[id];
},

Just creating and destroying dijit._Widget 500 times will increase the memory footprint by .5MB! The graph:

No image "iebug_graph.jpg" attached to Ticket #5382

Fortunately I've found the workaround:

  1. Make a new hash.
  2. Mixin the old hash's contents.
  3. Delete the old hash.
  4. Replace the reference to the old hash with the new hash.
  5. CollectGarbage?()

For instance, in dijit/manager.js:

remove: function(/*String*/ id){
	delete this._hash[id];
	// IE seems to leave remnants of the reference anyway in memory
	// need to delete the entire hash to clean up
	var newhash={};
	dojo.mixin(newhash,this._hash);
	delete this._hash;
	this._hash=newhash;
	if(dojo.isIE){
		// invoke the GC for best results
		CollectGarbage();
	}
},

This code creates a drastic improvement in memory footprint for plain _Widgets! Of course more complicated widgets, like Menu, will still eat up a lot of memory. My guess is that dojo.connects are also failing to be cleared from memory, whether they are hashing/being hashed, or are just using plain arrays. Basically, wherever we delete/splice/whathaveyou something from a hash/array, we have to paste in this workaround to keep memory down.

comment:10 Changed 11 years ago by bill

Interesting (and depressing), particularly that this occurs on IE7 too.

I think recreating a hash every time an element is added would be unacceptable because of the CPU cost (and also btw I'm surprised it doesn't leak more memory than the current code). I suppose we could have some kind of Hash class that recreated the hash every 100 inserts or so... it's a pretty radical change though.

In any case it's good to know what's going on.

comment:11 Changed 8 years ago by Colin Snover

Priority: highblocker

Bulk update of open ticket priorities.

comment:12 Changed 8 years ago by bill

Resolution: wontfix
Status: newclosed

Closing this, it's unlikely we'll workaround this IE bug given the age of this ticket and the fact that IE6 and IE7 are fast becoming extinct.

Note: See TracTickets for help on using tickets.