Categories:

Introducing the closure

Here is another piece of code. Instead of appending the script inline, we attach it externally:

[Exhibit 4 - Leak test with a closure]

<html>
<head>
<script type="text/javascript">
    function LeakMemory(){
        var parentDiv = document.createElement("div");
                          parentDiv.onclick=function(){
            foo();
        };

        parentDiv.bigString = 
          new Array(1000).join(new Array(2000).join("XXXXX"));
    }
</script>
</head>
<body>
<input type="button" 
       value="Memory Leaking Insert" onclick="LeakMemory()" />
</body>
</html>

If you don't know what a closure is, there are very good references on the web where you may find it. Closures are very useful patterns; you should learn them and keep them in your knowledge base.

And here is the graph that shows the memory leak. This is somewhat different from the former examples. The anonymous function assigned to parentDiv.onclick is a closure that closes over parentDiv, which creates a circular reference between the JS world and DOM and creates a well-known memory leakage issue:

To generate leak in the above scenario, we should click the button, refresh the page, click the button again, refresh the page and so on.

Clicking the button without a subsequent refresh will generate the leak only once. Because, at each click, the onclick event of parentDiv is reassigned and the circular reference over the former closure is broken. Hence at each page load there is only one closure that cannot be garbage collected due to circular reference. The rest is successfully cleaned up.