none
IE appendChild/removeChild memory problem

    Question

  • I'm running Vista/ IE7 and when running the leak function the memory in taskmanager goes out of control.  I originally thought it might have been a vista/ie7 problem but after some testing it seems random.  I've tested it on multiple machines ie6/ie7 xp/vista/2003  and some will have the memory problem where it goes insane and other machines run it just fine with the memory staying close to what the browser had initially. 

    4 out of 5 vista machines had the problem

    1 out of 2 xp ie6 had the problem

    1 out of 4 xp ie7 had the problem

    0 of 1 server 03 ie6

     

    i tried running windows updates with no help does anyone else have this problem? any ideas?

     

    EDIT: it does occur in firefox as well

     

    <html>

    <head>

    </head>

    <body>

    <a href="javascript:leak();">leak</a>

    </body>

    </html>

    <script>

    var dialog;

    function add(){

    dialog = document.createElement('div');

    var html = '<div><p>Title</p></div>';

    dialog.innerHTML = html;

    document.body.appendChild(dialog);

    dialog.style.marginTop='200px';

    dialog.style.marginLeft='200px';

    }

    function remove(){

    document.body.removeChild(dialog);

    dialog=null;

    }

    function leak(){

    for(var i=0;i<100000;i++){

    add();

    remove();

    }

    alert('done');

    }

    </script>

    Wednesday, February 13, 2008 8:10 PM

Answers

  • I figured it out. I guess its a psuedo leak it gets cleaned up on page refresh but the problem is i guess the browser for whatever reason keeps a reference to the removed child somewhere so you have to set the innerHTML of the parent to a empty string and it fixes it. no idea why it was behaving differently on different machines tho.

     

    Thursday, February 14, 2008 3:20 PM

All replies

  • I figured it out. I guess its a psuedo leak it gets cleaned up on page refresh but the problem is i guess the browser for whatever reason keeps a reference to the removed child somewhere so you have to set the innerHTML of the parent to a empty string and it fixes it. no idea why it was behaving differently on different machines tho.

     

    Thursday, February 14, 2008 3:20 PM
  • function discardElement(element) {
             var garbageBin = document.getElementById('IELeakGarbageBin');
             if (!garbageBin) {
                     garbageBin = document.createElement('DIV');
                     garbageBin.id = 'IELeakGarbageBin';
                     garbageBin.style.display = 'none';
                     document.body.appendChild(garbageBin);
             }
             // move the element to the garbage bin
             garbageBin.appendChild(element);
             garbageBin.innerHTML = '';
    }

     

    seems to work for everything except forms

    • Proposed as answer by BitMSN Friday, February 19, 2010 5:25 PM
    Thursday, February 14, 2008 8:57 PM
  • I've just run into a very similar leak problem in both IE6 and 7, so it seems we're both finding that IE has some issues with cleaning up after DOM nodes that have been dynamically added then removed.

    Here's another way to fix the problem.  Additional mem-leak protection code could be added here as well to destroy all on* properties of the node and detach all of the node's event listeners.

    Hopefully ie8 will also recurse through its children in the builtin Element.prototype.removeChild : )

    function removeChildSafe(el) {
        //before deleting el, recursively delete all of its children.
        while(el.childNodes.length > 0) {
            removeChildSafe(el.childNodes[el.childNodes.length-1]);
        }
        el.parentNode.removeChild(el);
    }


    Sunday, February 24, 2008 3:32 PM
  • I will never understand why people post such Bull$hit on forums : none your crappy solutions work guys !!!

     

    On IE6 memory always increases no matter what code I tested on pathetic DOM.

     

     

     

    Saturday, March 22, 2008 1:29 AM
  • I tested the discardElement on IE6/7 and FF and it works for me for everything except forms.  Post your test code.

     

    On a side note: crying for solutions to problems and calling other peoples help ***, its a great way to get people to want to help you.

    Monday, March 24, 2008 2:22 PM
  • Kyle you simply made my day ;-) !!

    I just needed to convert a little for my winforms needs, I'll post the results in case it can help someone else:

    I First created a GarbageSPAN right after creating my webbrowser istance:
     
       HtmlDocument mydoc = _theWebBrowser.Document;
       HtmlElement mynewRow = mydoc.CreateElement("SPAN");
       mynewRow.Id = "GarbageSPAN";
       mynewRow.Style = "display:none";  
       mynewRow.InnerHtml = "";
       mydoc.Body.AppendChild(mynewRow);

    Then I created a method this way for taking out always the first div at the top:

    private void TakeOutFirstDiv()
      {  
       HtmlDocument mydoc = _theWebBrowser.Document;
       HtmlElement myFirstDIV=null;
       HtmlElement myOnlySPAN = null;

       HtmlElementCollection myColl = mydoc.GetElementsByTagName("DIV");  
       foreach (HtmlElement myDiv in myColl)
       {
        myFirstDIV = myDiv;
        break;
       }
       myOnlySPAN = mydoc.GetElementById("GarbageSPAN");
       myOnlySPAN.AppendChild(myFirstDIV);
       myOnlySPAN.InnerHtml = "";
      }

    This one works with IE6, IE7, and IE8 !! Thank you!

    Bit.
    Friday, February 19, 2010 5:25 PM