Skip to content
This repository

.adopt() causes memory leak #2127

Closed
gd0t opened this Issue · 16 comments

4 participants

gd0t Olmo Maldonado Arian Stolwijk John-David Dalton
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 Stolwijk
Owner

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

Arian Stolwijk
Owner

I'll try if I can reproduce this..

Arian Stolwijk
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..

Olmo Maldonado
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.

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;
        };
    }
Olmo Maldonado
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 Stolwijk arian closed this in a64bcbd
John-David Dalton

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.

Olmo Maldonado
Owner
John-David Dalton

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.

John-David Dalton

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/

Olmo Maldonado
Owner
John-David Dalton

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

John-David Dalton

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.