2012-06-23 77 views
3

下面的JavaScript代碼似乎泄漏內存,但我不知道爲什麼。我已經在Chrome 19和Firefox 12試過這種的代碼如下:Javascript removeChild內存泄漏?

<body> 
    <input id="add" type="button" value="add" onclick="add()" /> 
    <input id="remove" type="button" value="remove" onclick="remove()" /> 
    <div id="content"> 
    </div> 
</body> 

<script> 
    var count = 0; 

    function add() { 
     var i = 0, 
      newdiv; 

     for (i = 0; i < 10000; i++) { 
      newdiv = document.createElement('div'); 
      document.getElementById("content").appendChild(newdiv); 
      newdiv.setAttribute('id', "div" + count); 
      newdiv.innerHTML = "section " + count; 
      newdiv = null; 

      count = count + 1; 
     } 
    } 

    function remove() { 
     var i = 0; 
     for (i = 0; i < count; i++) { 
      document.getElementById("content").removeChild(document.getElementById("div" + i)); 
     } 
     count = 0; 
    } 

</script> 

當你不斷點擊添加按鈕,然後刪除按鈕Windows任務管理器內存不斷增加。當垃圾回收開始時,我預計內存會減少,但這似乎永遠不會發生。

所以,我的問題是:在這段代碼中是否有內存泄漏?如果是這樣,我該如何重構代碼來修復泄漏?

+0

它似乎在Chromium 19/Ubuntu 11.04中沒有內存問題。 –

+0

只是一個或兩個假設:'newdiv = null;'不等於'delete newdiv;'所以我可能認爲刪除比設置一個'null'好得多,實際上它不是'undefined' ...如果你使用本地存儲的文檔引用,並在閉包中執行所有內容,而不是在全局窗口上創建東西,甚至可以加速這件事,並減少內存使用率。 –

回答

2

我已經用Chrome 19.0測試過了,是的,你說得對,內存增加了。但大約30秒後,垃圾收集開始並且恢復正常。

0

我真的不能證明存在內存泄漏...但試想一下,你想有一個良好的體育比賽結束後清理10000瓶,需要一定的時間和資源;)

除了一些mabye有益的意見:使用閉包來封裝來自窗口對象的代碼。使用本地的文檔引用來避免範圍鏈演練,美國是一個片段來追加所有新的div,而不是每次訪問文檔,避免函數開銷(這些都只是建議,並不一定是你正在尋找的東西,但好的東西無論如何並應至少減少的問題有點:)

注:這些例子可能不是所有的工作完全跨瀏覽器

<body> 
    <input id="add" type="button" value="add"> 
    <input id="remove" type="button" value="remove"> 
    <div id="content"></div> 
</body> 
<script> 
    (function(DOC) { 
    var count = 0, getById = DOC.getElementById, createFragment = DOC.createDocumentFragment; 

    getById("add").addEventListener("click", function() { 
     var i = 0, 
      newdiv, 
      fragment = createFragment(); 

     for (; i < 10000; i++) { 
     newdiv = document.createElement('div'); 
     newdiv.id = "div" + count; 
     newdiv.innerHTML = "section " + count; 

     fragment.appendChild(newdiv); 
     delete newdiv; 
     } 
     getById("content").appendChild(fragment); 
     count = i; 
    }, false); 

    getById("remove").addEventListener("click", function() { 
     var element, i = 0; 
     for (; i < count; i++) { 
     element = getById("div" + i); 
     element.parentNode.removeChild(element); 
     } 
     count = 0; 
    }, false); 

    })(document); 
</script> 

我希望這有助於在任何解決或至少減少泄漏。 =)