Skip to main content

Memory leaks in JavaScript: What are they, how to spot them, how to create them


I've just been helping out with some interviews for a new developer and JavaScript is a major part of my role and the role we're recruiting for. To be honest the candidate wasn't that good and he didn't really understand JavaScript however in the interview he confused JavaScript with C# and started to discuss memory leaks in JS. I wanted to intervene however it was at that point I realised how little I know about memory leaks in JS apart from the fact they use up lots of memory and slow things down.



When thinking about it during the interview the only thing I can remember is OReilly's Def Guide (think it was the fourth edition) mentioning Mark and Sweep Garbage Collections. But that has been fading ever since I read that and I can't really expand on that. I've found very little on this subject that's clear and concise (apart from an article by Crockford by that wasn’t that clear).



Can someone please sum up as simply as possible: What are memory leaks in JS, how we can spot them, how to create them - I've been writing JS for years and this has totally knocked my knowledge and confidence as I've never really thought about it!


Source: Tips4allCCNA FINAL EXAM

Comments

  1. Actually, a "true" memory leak should never be possible in a language that has an automatic garbage collector. So if there is a memory leak, its always an error in the underlaying engine (for instance, the problem of named function expressions in some IE's).

    So, after we clarified that, it is still possible to gain a lot of memory with javascript and hold it without releasing. But that is not a true memory leak anyway. For instance, each function call creates a closure in ECMAscript. A lexical closure does, among other things, copy a reference to each parent context's data (activation and variable objects). So this needs some memory, especially if you're creating a lot of closures.

    Another example from the Javascript DOM world: We are creating a dynamic image using new Image() and set the source to a big image. Now, we have a reference to the image and it cannot get garbage collected until all references are gone or unused (even if a good memory tool will correctly tell you that the memory was used for images and not for javascript).

    But actually these are the only scenarios where you really can "leak" memory in this language. Again, it's not really leaking memory like a C malloc() where you forget to free() that section again. Since there is no dynamic memory managment in ECMAscript this stuff is totally out of your range.

    ReplyDelete
  2. var trolls = (function () {
    var reallyBigObject = eatMemory();

    // make closure (#1)
    // store reallyBigObject in closure
    (function () {
    var lulz = reallyBigObject;
    })();

    // make another closure (#2)
    return function () {
    return 42;
    };
    })();


    You would expect trolls to just be function () { return 42; } and you would expect the reallyBigObject to be removed and garbage collected.

    It's not, because if a single closure (#1) references a variable in the outer scope. Then all closures (#2 aswell) reference that variable.

    Just because you have a reference to #2 means you have a reference to reallyBigObject which won't be cleared until #2 is dead.

    Now consider your average closure heavy architecture where you wrap everything in closures and nest them 10 deep. You can see how easy it is to hold references to objects.

    Note the above details apply to v8. Any fully ES5 compliant browser would leak with

    var trolls = (function () {
    var reallyBigObject = eatMemory();
    return function () {};
    })();


    Because every inner function must have a reference to every closure variable defined in the outer scope, as per ES5. Most browsers take shortcuts and optimize this in a way that is not noticable.

    ReplyDelete
  3. Javascript is implemented different through all browsers. But there is a standard which all browsers should follow: ECMAscript.

    Consider that all modern languages implement its own versions of reference counting, so the best way to avoid memory leaks is referencing all unused variables to null.

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex