Обновление DOM через Javascript вызывает утечку памяти (только в Firefox?)

Я знаю, что этот вопрос задавался раньше, но ни один из ответов, похоже, не решает проблему. Я тестирую веб-страницу AJAX, которая обновляет элементы в DOM через javascript.

Каждую минуту на сервер запрашиваются новые данные, и DOM соответственно обновляется. Насколько я могу судить, использование памяти для этой страницы в Chrome увеличивается, но не слишком сильно (оно начинается с 40 МБ и достигает максимум 80 МБ). Однако в Firefox использование памяти начинается примерно со 120 МБ и может увеличиваться до более чем 400 МБ. Я прошел через Javascript с помощью Firebug, и кажется, что память расширяется больше всего, когда DOM обновляется с помощью моих методов Javascript.

Манипуляции с DOM просты, например:

var myTable = document.createElement("table");

var thead = document.createElement("thead");
var tr = document.createElement("tr");
var th = document.createElement("th");
th.appendChild(document.createTextNode("column1"));
tr.appendChild(th);

for(var test in obj.testObjs){
    th = document.createElement("th");
    th.appendChild(document.createTextNode(obj.testObjs[test].myVar));
    tr.appendChild(th);
}

Прежде чем добавлять новые данные к узлам в DOM, я сначала очищаю существующие данные. Я пробовал несколько способов, в том числе описанный здесь: Как удалить элементы DOM без утечек памяти?

А также простой способ, такой как:

function clearChildren(node){
    if(node != null){
        while (node.hasChildNodes()) node.removeChild(node.firstChild);
    }
}

Я также читал ( циклическое добавление/удаление узлов DOM вызывает утечку памяти в JavaScript? ), что браузеры начинают собирать мусор только тогда, когда он достигает определенного уровня? Это можно подтвердить? Я чувствую, что мой компьютер через некоторое время стал работать вяло из-за растущей памяти.

Я чувствую, что для этого должно быть решение, потому что протестированные мной коммерческие сайты, которые выполняют те же функциональные шаги, не вызывают роста использования памяти.

Любая помощь будет принята с благодарностью.

Спасибо.


person user172092    schedule 25.06.2011    source источник


Ответы (2)


innerHTML=''

Это неправильный способ подготовки переменной для обработки GC.
Вам нужно использовать функцию delete для элемента и каждого элемента, на который ссылается этот элемент.
Много, верно?
Именно поэтому у нас есть JS-библиотеки, где это было написано для нас. Я проверил код в Mootools (скачайте его и найдите destroy), и мне кажется, что он написан правильно.
Я думаю, что то же самое будет и в других библиотеках.

person Itay Moav -Malimovka    schedule 25.06.2011
comment
Спасибо за ответ - Mootools мешает JQuery? Я использую JQuery на своем сайте, и при попытке использовать функцию destroy() Mootools я получаю сообщение об ошибке JS, говорящее, что destroy() не является функцией - person user172092; 29.06.2011
comment
Вам нужно правильно настроить его, чтобы играть вместе (на моем сайте они прекрасно справляются). Например, вместо использования $ в коде, зависящем от Mootools, вам нужно использовать document.id('selectors...') - person Itay Moav -Malimovka; 30.06.2011
comment
Спасибо - кажется, что использование памяти сейчас не растет постоянно, и я вижу, что время от времени оно сокращается. Я ценю вашу помощь. - person user172092; 01.07.2011

Это можно подтвердить?

По-разному.

В общем, браузеры будут выполнять GC, когда им захочется, и эвристика может меняться довольно часто. Я подозреваю, что если вы попробуете Firefox каждую ночь, вы увидите совершенно другое поведение, чем то, что вы описали выше. С момента выпуска Firefox 5 в эвристику было внесено как минимум 2 изменения.

person Boris Zbarsky    schedule 29.06.2011
comment
Какая у нас сейчас версия ФФ? я потерял след - person Itay Moav -Malimovka; 30.06.2011
comment
Firefox 5 — это текущая стабильная версия. 6 запланирован на середину августа. - person Boris Zbarsky; 30.06.2011