Skip to content

.adopt() causes memory leak #2127

Closed
pronouncedJerry opened this Issue Nov 16, 2011 · 16 comments

4 participants

@pronouncedJerry

If you use .adopt() versus .inject() or .grab() you'll notice a memory leak in IE7, possibly IE8.

Example:

var newDiv = new Element('div', { id: 'newrDiv' });
$(document.body).adopt(newDiv);

@pronouncedJerry

After further investigation, if I change the following in adopt:

from:
elements = Array.flatten(arguments)

to:
elements = arguments

The leak disappears.

@pronouncedJerry

My colleague followed up on my findings and stated the following:

After digging a little deeper into the code, I found the culprit: instanceof. Apparently if you call instanceof on a “non-object” in IE, memory gets leaked (http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak). So, this isn’t a mootools bug, it’s a bug in IE itself.

@arian
MooTools member
arian commented Nov 21, 2011

Sounds interesting (and fun, memory leaks in IE7)...

@arian
MooTools member
arian commented Nov 21, 2011

I'll try if I can reproduce this..

@arian
MooTools member
arian commented Nov 21, 2011

I can't really reproduce this with a small testpage. It seems to use more memory after each refresh indeed, however not a lot more than an simple page with only window.addEvent('domready', function(){ ... }); or window.onload.

Now i'm not memory IE leak expert, so maybe I'm doing something different then you? I found this little program called 'Drip' (via http://blogs.msdn.com/b/ie/archive/2007/11/29/tools-for-detecting-memory-leaks.aspx) for viewing the memory usage. I don't know if there are other tools for analyzing memory leaks and where they come from..

@ibolmo
MooTools member
ibolmo commented Dec 10, 2011

I'm having trouble reproducing this as well. I've gone as far as identifying a few leaks in Element.js that I've cleaned up and will create a PR for, and will continue to try to find the other leaks, but it'd be best if @gd0t provided us with a procedure on how to reproduce.

@ibolmo ibolmo referenced this issue Dec 11, 2011
Merged

Fixes #2127 #2166

@ibolmo ibolmo was assigned Dec 11, 2011
@pronouncedJerry

Thank you!

I was simply using Process Explorer to track the usage. http://technet.microsoft.com/en-us/sysinternals/bb896653

It appears that the calling of instanceof on 'non-objects' (mootools.js flatten()) causes the memory leaks in IE. http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak

We ended up implementing the following:

if(Browser.ie) {
        instanceOf = this.instanceOf = function(item, object) {
            if (item == null) return false;
            // Avoid calling instanceof on certain "non-objects" to prevent memory leaks in IE
            if (!item.hasOwnProperty) return false;
            var constructor = item.$constructor || item.constructor;
            while (constructor){
                if (constructor === object) return true;
                constructor = constructor.parent;
            }
            return item instanceof object;
        };
    }
@ibolmo
MooTools member
ibolmo commented Dec 20, 2011

Thanks @gd0t. I'll add another issue to test for instanceOf leaks. In the mean time, you should reconsider using Process Explorer and opt to use sIEve. A couple of reason why:

  • Process Explorer looks at a whole process. Not very granular (e.g. you don't know which nodes are leaked).
  • There are fake leaks that stay in memory until the browser is closed. We should minimize these, but not much we can do.

Otherwise, I think it's fine to use Process Explorer; but I think you'll find sIEve much more detailed tool.

@arian arian closed this in a64bcbd Jan 9, 2012
@jdalton
jdalton commented Jan 9, 2012

Tools like sIEve give false positives and can cause devs to waste time. I find it's best to use use Process Explorer and a simplified test case to locate leaks. I am aware of the instanceof leak and try to avoid it in places like Benchmark.js. That said not every dummy element created has to be nulled.

@ibolmo
MooTools member
ibolmo commented Jan 9, 2012
@jdalton
jdalton commented Jan 9, 2012

No blog post at the moment, but for some tricky IE6 memory leaks it may require early versions of XP pre SP2, which can be a pain to get a hold of.

I was able to reproduce leaks without having to scrounge up an old IE6 Win 2K/XP install by using Multiple-IE, but those browsers are really unstable so try to get the real deal if possible.

@jdalton
jdalton commented Jan 9, 2012

Here is a blog post I did over a nice single page memory leak in IE associated with removeChild.
http://allyoucanleet.com/2011/02/16/exploring-the-removechild-single-page-memory-leak/

@ibolmo
MooTools member
ibolmo commented Jan 9, 2012
@jdalton
jdalton commented Jan 9, 2012

How did you narrow the leak to replaceChild?

The removeChild leak was known at the time. I remember reading about it in an excerpt here or some place similar.

code snippet

@jdalton
jdalton commented Jan 9, 2012

When doing research into IE's event handler leaks I had to whittle the code down to a small snippet, which took some time (I used Process Explorer here again).

The result can be seen in @bryanforbes post over the Internet Explorer event handler leak under the "Fixing It By Global Reference" section.

@pronouncedJerry

Big thanks to all of you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.