Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

.adopt() causes memory leak #2127

Closed
gd0t opened this Issue · 16 comments

4 participants

@gd0t

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);

@gd0t

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

from:
elements = Array.flatten(arguments)

to:
elements = arguments

The leak disappears.

@gd0t

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
Owner

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

@arian
Owner

I'll try if I can reproduce this..

@arian
Owner

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
Owner

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
Merged

Fixes #2127 #2166

@ibolmo ibolmo was assigned
@gd0t

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
Owner

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
@jdalton

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
Owner
@jdalton

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

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
Owner
@jdalton

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

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.

@gd0t

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.