Во-первых, от того, будет ли возвращена память в систему, зависит от сборщика мусора Javascript (gc), и поэтому результаты будут различаться в зависимости от браузера.
Трудно измерить использование памяти, глядя на процесс, так как существует несколько уровней управления памятью. Чтобы увидеть, как это может повлиять, подумайте, что огромный объект javascript мог быть удален навсегда, но эта память, возможно, еще не была возвращена обратно в операционную систему, потому что веб-браузер может сохранить его на случай, если вам понадобится создавать больше больших объектов. Другой пример - большинство подпрограмм gc запускаются только периодически, поэтому возможно, что объект все еще находится в памяти, но будет восстановлен позже.
Однако, довольно легко определить, утечка памяти у конкретной операции, поскольку все, что вам нужно сделать, это повторить ее в бесконечном цикле . например,
- удалить ссылки на существующие HTML-элементы
- создание новых HTML-элементов
- добавить их на страницу
Попробуйте этот код:
var div = document.getElementById("test")
while(true) {
// remove operation, change me
while(div.firstChild) {
div.removeChild(div.firstChild);
}
// create some new content
for(var i=0; i<1000; i++) {
var p = document.createElement('p');
p.appendChild(document.createTextNode('text'));
div.appendChild(p);
}
}
Мои результаты в Chrome с использованием диспетчера задач (shift + esc):
- Если цикл будет работать бесконечно, ничего не удаляя, в конечном итоге появится экран «Aw! Snap», который показывает, что память исчерпана
- Использование метода removeChild приводит к стабилизации использования памяти на уровне 750 МБ
- Использование метода innerHTML приводит к стабилизации использования памяти на уровне 750 МБ
Если память не протекает, вы заметите схему, подобную этой: увеличивается до 300, падает до 150, увеличивается до 400, падает до 250, в конечном итоге стабилизируется. Это система управления памятью, исчерпывающая память, запускающая gc для восстановления памяти, которая была освобождена, и каждый раз увеличивающая доступный объем памяти до достижения мягкого предела, который был установлен, чтобы избежать влияния процесса на других. Это типичная схема управления памятью, и вы можете узнать больше, прочитав эту статью в Википедии: http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)
Поскольку оба результата стабилизируются, я пришел к выводу, что (по крайней мере для Chrome) оба метода работают одинаково, хотя в других браузерах вы можете получить разные результаты.
Поскольку разницы, по-видимому, нет, следует использовать removeChild, поскольку innerHTML не включен в стандарт W3C и не одобряется некоторыми разработчиками. Подробнее здесь: Альтернатива для innerHTML?
Причина того, что innerHTML и removeChild не имеют различий, заключается в том, что внизу они оба должны отменить ссылку на элементы, чтобы они не были видны на экране. Утечки памяти чаще всего возникают, когда у вас есть циклические ссылки (A указывает на B, B указывает на A, никто больше не указывает ни на что), но это проблема только в старых браузерах. Эта ссылка содержит несколько хороших рекомендаций о том, как избежать утечек памяти в js: Подводные камни управления памятью Javascript?