Memory Leaks, createElement, and Form Controls

Discussion in 'Javascript' started by dhtml, Oct 5, 2008.

  1. dhtml

    dhtml Guest

    (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 HTMLInputElement]

    (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:
    http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/db8447c9ef6b0710?tvc=1

    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=utf-8">
    <style type="text/css">
    input { display: none; }
    </style>
    </head>
    <body>
    <h1>Adding DIV to DIV</h1>
    <button onclick="create()">create()</button>
    <button onclick="destroy()">destroy()</button>
    <button onclick="periodicCreate()">periodicCreate()</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.getElementById('mon'),
    keyMon = document.getElementById('mon2').firstChild;
    var p = document.getElementById('cont');
    keys = [];
    function create() {
    var n = "n" + +new Date;
    keys.push(n);
    setTimeout(addInputs, 10);
    }

    function addInputs() {
    var inp = document.createElement('div'),
    c,
    n = keys[keys.length-1];
    for(var i = 0; i < 1000; i++) {
    c = inp.cloneNode(false);
    // 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(periodicCreate.i == +document.getElementById('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.
    dhtml, Oct 5, 2008
    #1
    1. Advertising

  2. 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 HTMLInputElement]


    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
    Thomas 'PointedEars' Lahn, Oct 5, 2008
    #2
    1. Advertising

  3. 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
    Stanimir Stamenkov, Oct 5, 2008
    #3
  4. 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>
    Thomas 'PointedEars' Lahn, Oct 5, 2008
    #4
  5. dhtml

    dhtml Guest

    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.
    dhtml, Oct 5, 2008
    #5
  6. dhtml

    dhtml Guest

    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.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 HTMLInputElement]

    >
    > 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
    dhtml, Oct 5, 2008
    #6
  7. 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::createElement. 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 HTMLInputElement]

    > >
    > > 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 "destructing" the
    other, it would stand to reason that the memory usage did not
    decrease, other factors aside.


    PointedEars
    Thomas 'PointedEars' Lahn, Oct 6, 2008
    #7
  8. On 5 Okt., 19:10, dhtml <> wrote:
    > 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
    Thomas 'PointedEars' Lahn, Oct 6, 2008
    #8
  9. dhtml

    dhtml Guest

    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::createElement. 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.forms[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 "destructing" 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=""><input name="foo"><input 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.forms[0].bar+'<br>');
    document.write('elements.foo: '+document.forms[0].elements.foo);
    </script>
    </pre>
    </body>
    </html>

    Result:
    foo: [object HTMLInputElement]
    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
    dhtml, Oct 6, 2008
    #9
  10. dhtml

    dhtml Guest

    Thomas 'PointedEars' Lahn wrote:
    > On 5 Okt., 19:10, dhtml <> wrote:
    >> 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
    dhtml, Oct 6, 2008
    #10
  11. dhtml

    Nacho Guest

    On Oct 5, 12:00 am, dhtml <> wrote:
    > 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.
    Nacho, Oct 13, 2008
    #11
  12. dhtml

    dhtml Guest

    Nacho wrote:
    > On Oct 5, 12:00 am, dhtml <> wrote:



    >
    > 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.javascript FAQ <URL: http://jibbering.com/faq/ >
    dhtml, Oct 17, 2008
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Christine
    Replies:
    0
    Views:
    429
    Christine
    Apr 6, 2004
  2. Replies:
    7
    Views:
    1,115
    Peter Koch Larsen
    Mar 29, 2005
  3. cs

    malloc and memory leaks

    cs, Jul 9, 2005, in forum: C Programming
    Replies:
    18
    Views:
    571
  4. Lindsay

    GDI objects and memory leaks

    Lindsay, Dec 14, 2005, in forum: C++
    Replies:
    1
    Views:
    315
    Bob Hairgrove
    Dec 14, 2005
  5. Replies:
    4
    Views:
    118
Loading...

Share This Page