2012-06-23 5 views
3

Следующий код javascript, кажется, течет памятью, но я не уверен, почему. Я попытался это в хроме 19 и Firefox 12. Код ниже:Javascript removeChild memory leak?

<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 Task Manager продолжает расти , Я ожидал, что память уменьшится в какой-то момент, когда сбор мусора начнется, но это, похоже, не происходит.

Итак, мои вопросы: есть ли утечка памяти в этом коде? И если так как я могу реорганизовать код, чтобы исправить утечку?

+0

Кажется, что без проблем с памятью в Chromium 19/Ubuntu 11.04. –

+0

только одно или два предположения: 'newdiv = null;' не равно 'delete newdiv', поэтому я мог бы подумать, что удаление лучше, чем установка некоторого значения в' null', который фактически не является 'undefined' ... если вы используете локально хранящаяся ссылка на документ и выполнение всего в закрытии, а не создание материала в глобальном оконном обэте, даже ускорит это и уменьшит использование памяти imho –

ответ

2

Я тестировал это с помощью Chrome 19.0 и да, вы правы, память увеличивается. Но примерно через 30 секунд вывоз мусора начинается, и он возвращается к норме.

0

Я не могу доказать, есть утечка памяти ... но только представьте, что вы хотите очистить 10000 бутылок после хорошей спортивной игры, занимает некоторое время и ресурсы;)

кроме некоторых mabye полезных комментариев: используйте закрытие для инкапсулирования этого кода из оконного объекта. используйте локальную ссылку на документ, чтобы избежать прокрутки в цепочке цепей, usa фрагмент, чтобы добавить все новые 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> 

Я надеюсь, что это помогает в любом решении или, по крайней мере, уменьшения утечки. =)