开发者

Cyclic adding/removing of DOM nodes causes memory leaks in JavaScript?

I'm trying to display dynamically changeable data manipulating with DOM elements (adding/removing them). I found out a very strange behavior of almost all browsers: after I removed a DOM element and then add a new one the browser is not freeing the memory taken by the removed DOM item. See the code below to understand what I mean. After we run this page it'll eat step-by-step up to 150 MB of memory. Can anyone explain me this strange behavior? Or maybe I'm doing something wrong?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
  <script type="text/javascript">
     function redrawThings() {
         // Removing all the children from the container
         var cont = document.getElementById("container");
         while ( cont.childNodes.length >= 1 ) {
            cont.removeChild(cont.firstChild);
         }

         // adding 1000 new children to the container
         for (var i = 0; i < 1000; i++) {
             var newDiv = document.createElement('div');
             newDiv.innerHTML = "Preved medved "  + i;
             cont.appendChild(newDiv);             
         }         
     }  
  </script>
  <style type="text/css">
    #container {
        border: 1px solid blue;
    }
  </style>
</head>
<body onload='setInterval("redrawThings()", 200);'>
  <div id="container"> </div>
</body>
</开发者_Python百科html>


I can't reproduce this on FF 3.6.8/Linux, but 200 ms for a timer is rather small with that much of DOM re-rendering. What I notice on my machine is that when doing JavaScript-intensive things besides running this script, like typing in this answer box, memory usage increases, but is released again when I stop typing (in my case, to something around 16% of memory usage).

I guess that in your case the browser's garbage collector just doesn't have enough ‘free time’ to actually remove those nodes from memory.


Not sure if it'll affect timing, and it's probably really bad practice, but instead of looping through the child nodes, could you not just set the innerHTML of the div to "" ??


It's because removing a Node from the DOM Tree doesn't delete it from memory, it's still accessible, so the following code will work:

var removed = element.removeChild(element.firstChild);
document.body.appendChild(removed);

That code will remove the first child from element, and then after it has been removed, append it to the end of the document. There really is nothing you can do except make your code more efficient with less removals.

For more info, check out the Node.removeChild page at the Mozilla Developer Center.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜