Memory Leaks, createElement, and Form Controls

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • dhtml

    Memory Leaks, createElement, and Form Controls

    (originally mis-posted on m.p.s.jscript.. .)

    I've just closed all windows in Firefox and its using 244MB of memory.

    I have no idea why. I had GMail open, a page from unicode, the CLJ FAQ.

    I've noticed that createElement leaks. It's obvious with form controls
    because the form keeps the control name as a property.

    Example:

    <!doctype html>
    <body>
    <form><input name="foo"/></form>

    <script>
    document.forms[0].foo;
    document.forms[0].innerHTML = "";
    document.write( document.forms[0].foo);
    </script>
    </body>

    Will output:
    [object HTMLInputElemen t]

    (or similar implementation-dependent string).

    If a node is added to the document, memory is allocated for that node.
    When that node is removed, the memory usage goes back down, but not to
    where it was before.

    So FORM controls leak memory. This came up here:


    So what happens if I create, say 100 divs, then remove them?

    Using Firefox 3.0.1
    Well, I did that. I restarted Firefox. and noted the memory usage at "53mb".

    I filled in "100" for the text input and clicked "periodicCreate ()".

    It reached 100 after a less than a minute. I checked the memory usage
    again and it was 89.38mb.

    I clicked "destroy" and waited a few minutes, watching the memory
    increase and Firefox became unresponsive and CPU spiked to 100%.

    "destroy" completed several minutes later, and I noted the memory usage
    at 85.00mb.

    A minute later, real memory remains at around 85mb. I reloaded the page.
    85mb. I navigated to google.com. Still at 85mb.

    Here is my test page:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <title>div Memory Leak</title>
    <meta http-equiv="Content-Type" content="text/html;charset=ut f-8">
    <style type="text/css">
    input { display: none; }
    </style>
    </head>
    <body>
    <h1>Adding DIV to DIV</h1>
    <button onclick="create ()">create()</button>
    <button onclick="destro y()">destroy() </button>
    <button onclick="period icCreate()">per iodicCreate()</button>
    <input type="text" value="20" style="display: block" id='per'>
    <pre id="mon">
    Check memory consumption before starting.
    </pre>
    <pre id="mon2">
    -
    </pre>
    <div id='cont'><!-- if the form element tag is changed to "div",
    the leak does not occur --></div>
    <script type='text/javascript'>
    var mon = document.getEle mentById('mon') ,
    keyMon = document.getEle mentById('mon2' ).firstChild;
    var p = document.getEle mentById('cont' );
    keys = [];
    function create() {
    var n = "n" + +new Date;
    keys.push(n);
    setTimeout(addI nputs, 10);
    }

    function addInputs() {
    var inp = document.create Element('div'),
    c,
    n = keys[keys.length-1];
    for(var i = 0; i < 1000; i++) {
    c = inp.cloneNode(f alse);
    // add a title property,
    // to increase memory.
    c.title = "T" + i;
    p.appendChild(c );
    }
    keyMon.data += (keys.length) + " name prefix: " + n + " please
    wait.\r\n";
    addInputs.done( );
    }
    addInputs.done = function(){};

    function periodicCreate( ) {
    if(periodicCrea te.i == +document.getEl ementById('per' ).value)
    return;
    create();
    addInputs.done = function() {
    periodicCreate. i++;
    periodicCreate( );
    };
    }
    periodicCreate. i = 0;

    function destroy() {
    mon.innerHTML = "setting innerHTML = ''. Please wait...";
    p.innerHTML = "";
    mon.innerHTML = "done. Check memory consumption again.";
    }
    </script>

    </body>
    </html>
    =============== =============== =============

    So, Firefox leaks memory with createElement/appendChild.
  • Thomas 'PointedEars' Lahn

    #2
    Re: Memory Leaks, createElement, and Form Controls

    dhtml wrote:
    I've just closed all windows in Firefox and its using 244MB of memory.
    Wait till the FIREFOX.EXE process was terminated (as initiated by closing
    all of its windows), then it will use 0M of memory. Besides, which memory
    exactly?
    [...]
    I've noticed that createElement leaks. It's obvious with form controls
    because the form keeps the control name as a property.
    You have noticed nothing of the sort.
    Example:
    >
    <!doctype html>
    >
    <body>
    <form><input name="foo"/></form>
    >
    <script>
    That is not even remotely Valid, and you are complaining?
    document.forms[0].foo;
    This does not do anything except reference resolution.
    document.forms[0].innerHTML = "";
    So you are trying to create an empty `form' element, which is not Valid.

    <http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.3>
    document.write( document.forms[0].foo);
    </script>
    </body>
    >
    Will output:
    [object HTMLInputElemen t]
    Works as designed. Good Thing.
    (or similar implementation-dependent string).
    So you are not even complaining only about Gecko-based UAs in the first
    place? Because there is only one Gecko DOM implementation.
    [...]
    Here is my test page:
    >
    <!DOCTYPE html>
    Not Valid again.
    [...]
    So, Firefox leaks memory with createElement/appendChild.
    That is an incorrect assumption. Apparently you have neither understood
    HTML, the DOM, or Windows memory management nor how garbage collection
    works: an object that is no longer being referred to is eventually marked
    for garbage collection that may or may not come later. It would be very
    inefficient would garbage collection take place immediately after an object
    would no longer being referred to.


    PointedEars

    Comment

    • Stanimir Stamenkov

      #3
      Re: Memory Leaks, createElement, and Form Controls

      On 05.10.2008 г. 14:33, /Thomas 'PointedEars' Lahn/:
      dhtml wrote:
      >
      ><!doctype html>
      >>
      ><body>
      ><form><input name="foo"/></form>
      >>
      ><script>
      >
      That is not even remotely Valid, and you are complaining?
      >
      >[...]
      >Here is my test page:
      >>
      ><!DOCTYPE html>
      >
      Not Valid again.
      The later is well-formed XML (I guess SGML, too) DOCTYPE
      declaration. The former appears to be valid HTML 5
      <http://www.w3.org/html/wg/html5/#the-doctype>.

      --
      Stanimir

      Comment

      • Thomas 'PointedEars' Lahn

        #4
        Re: Memory Leaks, createElement, and Form Controls

        Stanimir Stamenkov wrote:
        On 05.10.2008 г. 14:33, /Thomas 'PointedEars' Lahn/:
        >dhtml wrote:
        >><!doctype html>
        >>[...]
        >><!DOCTYPE html>
        >Not Valid again.
        >
        The later is well-formed XML (I guess SGML, too) DOCTYPE
        declaration.
        Well-formed maybe, but not Valid.
        The former appears to be valid HTML 5
        <http://www.w3.org/html/wg/html5/#the-doctype>.
        "HTML 5" is a Working Draft in its early stages, and of disputable authority.


        PointedEars
        --
        Use any version of Microsoft Frontpage to create your site.
        (This won't prevent people from viewing your source, but no one
        will want to steal it.)
        -- from <http://www.vortex-webdesign.com/help/hidesource.htm>

        Comment

        • dhtml

          #5
          Re: Memory Leaks, createElement, and Form Controls

          Stanimir Stamenkov wrote:
          On 05.10.2008 г. 14:33, /Thomas 'PointedEars' Lahn/:
          >dhtml wrote:
          >>
          >><!doctype html>
          >>>
          >
          The later is well-formed XML (I guess SGML, too) DOCTYPE declaration.
          The former appears to be valid HTML 5
          <http://www.w3.org/html/wg/html5/#the-doctype>.
          >
          That doctype triggers standards mode. It won't pass the validator.

          If desired, a full URI-doctype can be added to achieve the same effect.

          Lets try to not focus on the extraneous noise and keep this focused and
          on-topic.

          Comment

          • dhtml

            #6
            Re: Memory Leaks, createElement, and Form Controls

            Thomas 'PointedEars' Lahn wrote:
            dhtml wrote:
            >I've just closed all windows in Firefox and its using 244MB of memory.
            >
            Wait till the FIREFOX.EXE process was terminated (as initiated by closing
            all of its windows), then it will use 0M of memory. Besides, which memory
            exactly?
            >
            Closing all of the windows does not result in 0M of memory being used
            (real memory).

            >[...]
            >I've noticed that createElement leaks. It's obvious with form controls
            >because the form keeps the control name as a property.
            >
            You have noticed nothing of the sort.
            >
            The example was shortened for brevity. Validating the html does not
            change the result.

            >Example:
            >>
            ><!doctype html>
            >>
            ><body>
            ><form><input name="foo"/></form>
            >>
            ><script>
            >
            That is not even remotely Valid, and you are complaining?
            >
            >document.for ms[0].foo;
            >
            This does not do anything except reference resolution.
            >
            >document.for ms[0].innerHTML = "";
            >
            So you are trying to create an empty `form' element, which is not Valid.
            >
            <http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.3>
            >
            >document.write (document.forms[0].foo);
            ></script>
            ></body>
            >>
            >Will output:
            >[object HTMLInputElemen t]
            >
            Works as designed. Good Thing.
            >
            This is the result in Firefox. Opera has a different result. The first line:
            document.forms[0].foo;

            Does affect the result in Firefox.
            So you are not even complaining only about Gecko-based UAs in the first
            place? Because there is only one Gecko DOM implementation.
            >
            I'm not complaining, you are.

            >So, Firefox leaks memory with createElement/appendChild.
            >
            That is an incorrect assumption. Apparently you have neither understood
            HTML, the DOM, or Windows memory management nor how garbage collection
            works: an object that is no longer being referred to is eventually marked
            for garbage collection that may or may not come later. It would be very
            inefficient would garbage collection take place immediately after an object
            would no longer being referred to.
            >
            I'm not on Windows. Keeping the browser open for a long time after the
            test complets doesn't change the result. I actually went away for 5
            minutes and came back and memory usage was the same.
            >
            PointedEars

            Comment

            • Thomas 'PointedEars' Lahn

              #7
              Re: Memory Leaks, createElement, and Form Controls

              dhtml wrote:
              Thomas 'PointedEars' Lahn wrote:
              dhtml wrote:
              I've just closed all windows in Firefox and its using 244MB of memory.
              Wait till the FIREFOX.EXE process was terminated (as initiated by closing
              all of its windows), then it will use 0M of memory.  Besides, which memory
              exactly?
              >
              Closing all of the windows does not result in 0M of memory being used
              (real memory).
              (Did you notice that I was talking about the process's memory usage?)

              Then you have either not waited long enough or you have much greater a
              problem than supposed memory leaks from D::createElemen t. Probably an
              extension blocking Firefox's termination (BTDT) as AFAIK Firefox does
              not provide the Quick Start feature of Mozilla that keeps it running
              in the background (CMIIW).
              [...]
              I've noticed that createElement leaks. It's obvious with form controls
              because the form keeps the control name as a property.
              You have noticed nothing of the sort.
              >
              The example was shortened for brevity. Validating the html does not
              change the result.
              True, but changing the markup might.
              document.forms[0].foo;
              This does not do anything except reference resolution.
              document.forms[0].innerHTML = "";
              So you are trying to create an empty `form' element, which is not Valid..

              <http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-....>
              document.write( document.forms[0].foo);
              </script>
              </body>
              >
              Will output:
              [object HTMLInputElemen t]
              Works as designed.  Good Thing.
              >
              This is the result in Firefox. Opera has a different result.
              How different?
              The first line:
              document.forms[0].foo;
              >
              Does affect the result in Firefox.
              In what way?
              So you are not even complaining only about Gecko-based UAs in the first
              place?  Because there is only one Gecko DOM implementation.
              >
              I'm not complaining, you are.
              I am trying to analyse and rectify your incorrect assumptions instead.
              So, Firefox leaks memory with createElement/appendChild.
              That is an incorrect assumption.  Apparently you have neither understood
              HTML, the DOM, or Windows memory management nor how garbage collection
              works: an object that is no longer being referred to is eventually marked
              for garbage collection that may or may not come later.  It would be very
              inefficient would garbage collection take place immediately after an object
              would no longer being referred to.
              >
              I'm not on Windows.
              Right, I assumed from your posting in m.*.jscript before and other
              clues in your posting that you were. Incidentally, it would have been
              wise to name at least the exact version of Firefox you have been
              testing with, including the window framework and operating system it
              runs on, and the method of determining the process's memory usage
              (that may be flawed).
              Keeping the browser open for a long time after the
              test complets doesn't change the result. I actually went away for 5
              minutes and came back and memory usage was the same.
              In case you did not quit the Firefox process: garbage collection is
              not just a matter of time. However, as because of your inappropriate
              assignment at least one element object was not marked for garbage
              collection, and at least one other was created while "destructin g" the
              other, it would stand to reason that the memory usage did not
              decrease, other factors aside.


              PointedEars

              Comment

              • Thomas 'PointedEars' Lahn

                #8
                Re: Memory Leaks, createElement, and Form Controls

                On 5 Okt., 19:10, dhtml <dhtmlkitc...@g mail.comwrote:
                Stanimir Stamenkov wrote:
                On 05.10.2008 Ç. 14:33, /Thomas 'PointedEars' Lahn/:
                dhtml wrote:
                ><!doctype html>
                >
                The later is well-formed XML (I guess SGML, too) DOCTYPE declaration. š
                The former appears to be valid HTML 5
                <http://www.w3.org/html/wg/html5/#the-doctype>.
                >
                That doctype triggers standards mode.
                That DOCTYPE *declaration* may trigger "standards mode" (in whatever
                browser you have tested with), but that does not mean much for
                processing and the markup and handling it in DOM operations.
                It won't pass the validator.
                >
                If desired, a full URI-doctype can be added to achieve the same effect.
                The rest of your markup is not Valid as well, so changing the DOCTYPE
                declaration is not going to make a considerable difference.
                Lets try to not focus on the extraneous noise and keep this focused and
                on-topic.
                Noticing that the markup of a test case is not Valid is not extraneous
                noise.


                PointedEars

                Comment

                • dhtml

                  #9
                  Re: Memory Leaks, createElement, and Form Controls

                  Thomas 'PointedEars' Lahn wrote:
                  dhtml wrote:
                  >Thomas 'PointedEars' Lahn wrote:
                  >>dhtml wrote:
                  >>>I've just closed all windows in Firefox and its using 244MB of memory.
                  >>Wait till the FIREFOX.EXE process was terminated (as initiated by closing
                  >>all of its windows), then it will use 0M of memory. Besides, which memory
                  >>exactly?
                  >Closing all of the windows does not result in 0M of memory being used
                  >(real memory).
                  >
                  (Did you notice that I was talking about the process's memory usage?)
                  >
                  Then you have either not waited long enough or you have much greater a
                  problem than supposed memory leaks from D::createElemen t. Probably an
                  extension blocking Firefox's termination (BTDT) as AFAIK Firefox does
                  not provide the Quick Start feature of Mozilla that keeps it running
                  in the background (CMIIW).
                  >
                  Firefox should not terminate when the window is closed. Macs don't work
                  that way.

                  >This is the result in Firefox. Opera has a different result.
                  undefined.
                  >
                  How different?
                  >
                  >The first line:
                  >document.for ms[0].foo;
                  >>
                  >Does affect the result in Firefox.
                  >
                  If absent, the property will not be retrieved. The result of the second
                  getting of the |foo| property will be undefined. It seems that the
                  property will not be cached unless it is first gotten.

                  Firefox 3.0.1 on Mac.

                  >
                  In case you did not quit the Firefox process: garbage collection is
                  not just a matter of time. However, as because of your inappropriate
                  assignment at least one element object was not marked for garbage
                  collection, and at least one other was created while "destructin g" the
                  other, it would stand to reason that the memory usage did not
                  decrease, other factors aside.
                  The initial element would not be collectible.

                  We've got a page that increases memory and that memory doesn't get
                  reclaimed. It seems like a memory leak. I can increase it to the point
                  where Firefox will cause a freeze. entering "400" will do that in Firefox.

                  Here's Example 1 with valid html (to the same effect) and a |bar| input
                  that is not referenced in script, plus the elements.foo property.
                  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                  "http://www.w3.org/TR/html4/loose.dtd">
                  <html lang="en">
                  <head><title> </title></head>
                  <body>
                  <form action=""><inpu t name="foo"><inp ut name="bar"></form>
                  <pre>
                  <script type="text/javascript">
                  document.forms[0].foo;
                  document.forms[0].elements.foo;

                  // Clear out form's HTML.
                  document.forms[0].innerHTML = "";
                  document.write( 'foo: ' + document.forms[0].foo+'<br>');
                  document.write( 'bar: '+document.form s[0].bar+'<br>');
                  document.write( 'elements.foo: '+document.form s[0].elements.foo);
                  </script>
                  </pre>
                  </body>
                  </html>

                  Result:
                  foo: [object HTMLInputElemen t]
                  bar: undefined
                  elements.foo: undefined


                  Op9.5
                  foo: undefined
                  bar: undefined
                  elements.foo: undefined

                  After the innerHTML = "", there should be no more |foo| element in the
                  DOM. It is not gettable through elements collection, but can be gotten
                  directly off the form.

                  I disagree that this behavior is a Good Thing.

                  Garrett
                  >
                  >
                  PointedEars

                  Comment

                  • dhtml

                    #10
                    Re: Memory Leaks, createElement, and Form Controls

                    Thomas 'PointedEars' Lahn wrote:
                    On 5 Okt., 19:10, dhtml <dhtmlkitc...@g mail.comwrote:
                    >Stanimir Stamenkov wrote:
                    >>On 05.10.2008 Ç. 14:33, /Thomas 'PointedEars' Lahn/:
                    >>>dhtml wrote:
                    >>>><!doctype html>
                    >>The later is well-formed XML (I guess SGML, too) DOCTYPE declaration.
                    >>The former appears to be valid HTML 5
                    >><http://www.w3.org/html/wg/html5/#the-doctype>.
                    >That doctype triggers standards mode.
                    >
                    >Lets try to not focus on the extraneous noise and keep this focused and
                    >on-topic.
                    >
                    Noticing that the markup of a test case is not Valid is not extraneous
                    noise.
                    No, but stating that I don't understand HTML and so the test is invalid is.

                    I'm basing a "leak" as memory that does not get freed after a reasonable
                    amount of time (three minutes).

                    And now for safari 3.

                    Lauched, with blank window.
                    Real Memory Virtual Memory
                    14.64 MB 172.48 MB

                    Navigate some google searches, the FAQ page, and then open the test page:
                    Real Memory Virtual Memory
                    22.44 MB 190.75 MB

                    periodicCreate( )
                    400

                    Result:
                    Real Memory Virtual Memory
                    167.38 MB 458.46 MB

                    destroy()

                    Result:
                    Real Memory Virtual Memory
                    167.38 MB 458.46 MB

                    Navigate away.
                    Wait a few minutes.
                    Real Memory Virtual Memory
                    99.23 MB 557.16 MB

                    Minimize Safari.
                    Wait a few minutes.
                    Real Memory Virtual Memory
                    99.23 MB 557.16 MB

                    Un-minimize Safari, close (only) window, clear cache.
                    Wait a few minutes.
                    Real Memory Virtual Memory
                    91.09 MB 549.89 MB


                    I observed an increase in memory in Safari 3, and an eventual decrease,
                    but not to the previous amount of memory.

                    Garrett
                    >
                    >
                    PointedEars

                    Comment

                    • Nacho

                      #11
                      Re: Memory Leaks, createElement, and Form Controls

                      On Oct 5, 12:00 am, dhtml <dhtmlkitc...@g mail.comwrote:
                      Using Firefox 3.0.1
                      Well, I did that. I restarted Firefox. and noted the memory usage at "53mb".
                      >
                      I filled in "100" for the text input and clicked "periodicCreate ()".
                      >
                      It reached 100 after a less than a minute. I checked the memory usage
                      again and it was 89.38mb.
                      >
                      I clicked "destroy" and waited a few minutes, watching the memory
                      increase and Firefox became unresponsive and CPU spiked to 100%.
                      >
                      "destroy" completed several minutes later, and I noted the memory usage
                      at 85.00mb.
                      >
                      A minute later, real memory remains at around 85mb. I reloaded the page.
                      85mb. I navigated to google.com. Still at 85mb.
                      <snip>
                      So, Firefox leaks memory with createElement/appendChild.
                      No, it doesn't. There are, of course, various patterns that will
                      leak, but this isn't one of them.

                      What you're noticing is a side-effect of Firefox's memory management,
                      and this is working as designed. Firefox handles its own memory
                      allocation, and once it grabs memory from the operating system it
                      won't free it back to the OS. So if the browser needs more memroy, it
                      takes it, uses it, and once it no longer needs it anymore (e.g. you
                      delete your divs, close a tab, etc), Firefox keeps that memory just in
                      case it needs it later.

                      The real test for this would be to load your div test, notice the
                      memory size increase. Then, close your tab, open it up again and run
                      your div test again. If your Firefox.exe memory size doesn't increase
                      by 36M again, then you don't have a leak.

                      If, however, it goes from 53M to 89M, then on the second test attempt
                      it goes to 125M, then yes you have a legitimate leak.

                      Comment

                      • dhtml

                        #12
                        Re: Memory Leaks, createElement, and Form Controls

                        Nacho wrote:
                        On Oct 5, 12:00 am, dhtml <dhtmlkitc...@g mail.comwrote:
                        >
                        What you're noticing is a side-effect of Firefox's memory management,
                        and this is working as designed. Firefox handles its own memory
                        allocation, and once it grabs memory from the operating system it
                        won't free it back to the OS. So if the browser needs more memroy, it
                        takes it, uses it, and once it no longer needs it anymore (e.g. you
                        delete your divs, close a tab, etc), Firefox keeps that memory just in
                        case it needs it later.
                        >
                        The real test for this would be to load your div test, notice the
                        memory size increase. Then, close your tab, open it up again and run
                        your div test again. If your Firefox.exe memory size doesn't increase
                        by 36M again, then you don't have a leak.
                        >
                        (I am on a mac, BTW)
                        If, however, it goes from 53M to 89M, then on the second test attempt
                        it goes to 125M, then yes you have a legitimate leak.
                        Why does Firefox take memory when the page is not closed? After destroy,
                        there should a references to only one div.

                        Garrett

                        --
                        comp.lang.javas cript FAQ <URL: http://jibbering.com/faq/ >

                        Comment

                        Working...