Как уничтожить объект JavaScript?

Недавно я наткнулся на одно из своих приложений, которое потребляет слишком много памяти и увеличивается на 10 МБ/сек.

Итак, мне нравится знать, как уничтожить объект и переменные JavaScript, чтобы потребление памяти оставалось низким, а мой FF не мог быть уничтожен.

Я вызываю два моих скрипта каждые 8 ​​секунд без перезагрузки страницы.

function refresh() {
    $('#table_info').remove();
    $('#table').hide();
    if (refreshTimer) {
        clearTimeout(refreshTimer);
        refreshTimer = null ;
    }
    document.getElementById('refresh_topology').disabled=true; 
    $('<div id="preload_xml"></div>').html('<img src="pic/dataload.gif" alt="loading data" /><h3>Loading Data...</h3>').prependTo($("#td_123"));
    $("#topo").hide();
    $('#root').remove();
    show_topology();
}

Как я могу увидеть, какая переменная вызывает накладные расходы памяти, каков метод остановки выполнения этого процесса?


person Amit Shah    schedule 20.04.2012    source источник
comment
Рассматривали ли вы возможность изоляции частей вашего кода с помощью замыканий?   -  person YS.    schedule 20.04.2012
comment
Вы пробовали что-нибудь? Нравится использовать obj = null?   -  person Florian Margaine    schedule 20.04.2012
comment
А) Что делает show_topology? --- B) Вы когда-нибудь убирали то, что добавили к #td_123? --- C) Есть ли где-нибудь живая версия этого?   -  person Deestan    schedule 20.04.2012


Ответы (5)


Вы можете поместить весь свой код в одно пространство имен следующим образом:

var namespace = {};

namespace.someClassObj = {};

delete namespace.someClassObj;

Использование ключевого слова delete удалит ссылку на свойство, но на низком уровне сборщик мусора JavaScript (GC) получит больше информации о том, какие объекты нужно удалить.

Вы также можете использовать инструменты разработчика Chrome, чтобы получить профиль памяти вашего приложения и узнать, какие объекты в вашем приложении необходимо уменьшить.

person Yochai Akoka    schedule 20.04.2012
comment
Нажмите F12, чтобы получить инструменты разработчика. Перейдите на вкладку «Профиль» и нажмите «Пуск», чтобы запустить профиль. Вы можете выполнить профилирование на JS CPU, CSS Selector и сделать моментальный снимок кучи. - person Sarath; 20.04.2012
comment
или в последнем хроме введите слово производительность в консоли js - person David Morrow; 11.09.2013
comment
Возможно, это очевидно, но вы можете назвать свое пространство имен чем-то вроде g и сэкономить много времени. Используйте g.curItem=... вместо var curItem=... и сохраните ввод, а также разрешите g=undefined очистить все выделение глобальной памяти. - person David Spector; 25.12.2018

Вы не можете удалять объекты, они удаляются, когда на них больше нет ссылок. Вы можете удалить ссылки с помощью delete.

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

person CodeClown42    schedule 20.04.2012
comment
Не могли бы вы добавить пример циклической ссылки, которая не будет обнаружена сборщиком мусора? Прошу друга! ;) - person Emil Hemdal; 27.07.2018
comment
@emilhem, вы можете сослаться на сборщик мусора, и он удалит себя и Интернет - взрыв, возможно, создаст черную дыру в ЦЕРНе. Вы думали об этом примере? - person El Mac; 10.10.2019

Хотя существующие ответы дали решения для решения проблемы и второй половины вопроса, они не дают ответа на аспект самопознания первой половины вопроса, выделенного жирным шрифтом:

Как узнать, какая переменная вызывает накладные расходы памяти...?

Возможно, 3 года назад он не был таким надежным, но раздел Профили инструментов разработчика Chrome теперь достаточно мощный и многофункциональный. У команды Chrome есть содержательная статья о том, как его использовать и, следовательно, как сборка мусора (GC) работает в javascript, который лежит в основе этого вопроса.

Поскольку delete в основном является корнем принятого в настоящее время ответа Йохая Акоки, важно помнить, что делает удаление. Это не имеет значения, если не сочетается с концепциями работы GC в следующих двух ответах: если есть существующая ссылка на объект, она не очищается. Ответы более правильные, но, вероятно, не так ценятся, потому что требуют больше размышлений, чем просто написать «удалить». Да, одним из возможных решений может быть использование delete, но это не имеет значения, если есть еще одна ссылка на утечку памяти.

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

Поскольку здесь было упомянуто delete, также может быть полезно предоставить ресурс Понимание удаления. Хотя это не не входит ни в одно из реальных решений, которые действительно связаны со сборщиком мусора javascript.

person Shwaydogg    schedule 16.10.2015

Структурируйте свой код так, чтобы все ваши временные объекты располагались внутри замыканий, а не глобальных свойств пространства имен/глобальных объектов и выходили за рамки, когда вы с ними покончили. GC позаботится обо всем остальном.

person Oleg V. Volkov    schedule 20.04.2012

Я столкнулся с такой проблемой, и у меня возникла идея просто изменить innerHTML дочерних элементов проблемного объекта.

adiv.innerHTML = "<div...> the original html that js uses </div>";

Кажется грязным, но это спасло мне жизнь, так как работает!

person Sergio Abreu    schedule 10.06.2013