Как избавиться от элементов DOM в JavaScript, чтобы избежать утечек памяти - PullRequest
27 голосов
/ 20 апреля 2009

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

<form name="frmAJAX" method="post" action="Default.aspx?id=123456" id="frmAJAX">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" />
</div>
<div>
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" />
</div>
<div id="inner">
<!-- valid info here --!>
</div>
</form>

Далее я возьму вышеизложенное и вставлю его в новый элемент DOM, например:

   success: function(xhtml) {
        var tr = document.createElement('tr');
        var td = document.createElement('td');
        var container = document.createElement('div');

        obj.parentNode.parentNode.parentNode.insertBefore(tr, obj.parentNode.parentNode.nextSibling);

        td.appendChild(container);
        container.innerHTML = xhtml;
        tr.appendChild(td);

но после вышесказанного я использую jQuery для удаления неприятного мусора в aspnet

$('form:eq(1)').children().each(
    function() {
        if ($('form:eq(1)').find('div').filter(function() { return $(this).attr('id') == ''; }).remove());
    }
);

//Capture the remaining children
var children = $('form:eq(1)').children();

// Remove the form
$('form:eq(1)').remove();

// append the correct child element back to the DOM
parentObj.append(children);

У меня такой вопрос: при использовании IESieve я не замечаю никаких фактических утечек, но постоянно растущее число элементов DOM (таким образом, использование памяти).

Что я могу улучшить на стороне клиента, чтобы на самом деле убрать этот беспорядок? Примечание: оба IE7 / 8 показывают эти результаты.

РЕДАКТИРОВАТЬ : я наконец-то все заработал и решил написать короткое сообщение в блоге с полным исходным кодом.

Ответы [ 4 ]

12 голосов
/ 20 апреля 2009

Сложная задача - выяснить, где еще существует ссылка на поврежденные узлы.

Вы делаете это трудным путем - вы добавляете всю разметку на страницу, а затем удаляете ненужный материал. Я бы сделал это так:

var div = document.createElement('div');
// (Don't append it to the document.)

$(div).html(xhtml);

var stuffToKeep = $(div).find("form:eq(1)> *").filter(
  function() {
    return $(this).attr('id') !== '';
  }
);

parentObj.append(stuffToKeep);

// Then null out the original reference to the DIV to be safe.
div = null;

Это не гарантирует остановку утечки, но это хорошее начало.

7 голосов
/ 08 октября 2011
function discardElement(element) {
    var garbageBin = document.getElementById('IELeakGarbageBin');
    if (!garbageBin) {
        garbageBin = document.createElement('DIV');
        garbageBin.id = 'IELeakGarbageBin';
        garbageBin.style.display = 'none';
        document.body.appendChild(garbageBin);
    }
    // move the element to the garbage bin 
    garbageBin.appendChild(element);
    garbageBin.innerHTML = '';
}

Источник

2 голосов
/ 20 апреля 2009

remove() и тому подобное удаляют только элементы из DOM. Они все еще существуют где-то в памяти.

Это известная проблема с AJAX и Web 2.0. Вы мало что можете сделать, кроме разработки своего сайта и обеспечения того, чтобы вы иногда обновляли страницу, чтобы стереть вещи.

1 голос
/ 21 июля 2011

Я думаю, что «постоянно растущее потребление памяти» несколько неправильно понято. Это связано с управлением памятью внутри браузера (а также с Windows в целом) больше, чем с вашим JS-кодом. Менеджеры памяти обычно продолжают выделять (или избегать освобождения) до тех пор, пока они не должны. В системах, основанных на файлах подкачки и отображении памяти, выделение и освобождение памяти занимает очень много времени.

Так что, даже если ваши узлы освобождены от фактической структуры документа и DOM - вряд ли есть какой-либо способ измерить это из самой Windows в «реальном времени».

Попробуйте это:

  1. Запустите Taskmanager, переключитесь на вкладку процесса и просмотрите память вашего браузера

  2. Загрузите документ HTML, который выделяет 100 000 узлов, посмотрите, как увеличивается потребление памяти

  3. Нажмите кнопку на странице, которая освобождает все узлы. Обратите внимание, что мало что происходит с точки зрения освобождения памяти.

  4. Теперь сверните окно браузера и снова разверните его. В 90% всех случаев браузер теперь выгружает память, если не использует ее, и вы увидите, сколько она реально потребляет.

У вас может быть браузер, потребляющий 500 мегабайт оперативной памяти (не упомянутый выше пример), но когда вы минимизируете и увеличиваете его, он освобождает все, и внезапно он использует только 50 мегабайт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...