Як знищити об’єкт JavaScript?


81

Нещодавно я зіткнувся з одним своїм додатком, який споживає занадто багато пам'яті і збільшується на 10 МБ / сек.

Отже, мені подобається знати найкращий спосіб знищити об’єкт і змінні JavaScript, щоб споживання пам’яті залишалося низьким, а мій FF не міг бути знищений.

Я закликаю два мої JavaScript кожні 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();
}

Як я можу побачити, яка змінна спричиняє накладні витрати на пам’ять та метод, щоб зупинити виконання цього процесу?


1
Ви розглядали можливість виділення частин своїх кодів за допомогою закриття?
YS.

1
Ви щось пробували? Подобається користуватися obj = null?
Флоріан Маргайн

А) Що робить show_topology? --- Б) Чи ти коли-небудь очищаєш речі, які додаєш #td_123? --- В) Чи є десь жива версія цього?
Deestan

Відповіді:


93

Ви можете розмістити весь свій код в одному просторі імен, як це:

var namespace = {};

namespace.someClassObj = {};

delete namespace.someClassObj;

Використання deleteключового слова призведе до видалення посилання на властивість, але на низькому рівні збирач сміття JavaScript (GC) отримає більше інформації про те, які об’єкти потрібно відновлювати.

Ви також можете скористатися Інструментами розробника Chrome, щоб отримати профіль пам’яті програми та визначити, які об’єкти у вашій програмі потрібно зменшити.


12
Натисніть F12, щоб отримати інструменти розробника. Перейдіть на вкладку Профіль і натисніть Пуск, щоб запустити профіль. Ви можете зробити профілювання на JS CPU, CSS Selector, і ви можете зробити кучу знімка.
Сарат

3
або в останньому хрому введіть слово performance у консолі js
Девід Морроу,

Можливо, це очевидно, але ви можете назвати свій простір імен приблизно на кшталт "g" та заощадити багато набору тексту. Використовуйте g.curItem = ... замість var curItem = ... та заощаджуйте введення тексту, а також дозволяючи g = undefined очистити все виділення глобальної пам'яті.
Девід Спектор,

31

Ви не можете видалити об’єкти, вони видаляються, коли на них більше немає посилань. Ви можете видалити посилання за допомогою delete.

Однак, якщо ви створили кругові посилання у своїх об'єктах, можливо, вам доведеться роз'єднати деякі речі.


2
Не могли б ви додати приклад кругової довідки, яку збирач сміття не захопив би? Просити друга! ;)
emilhem

@emilhem ви можете посилатися на збирач сміття, і він видалить себе та Інтернет - можливо, імплозія створить чорну діру в ЦЕРНі. Ви замислювались над цим прикладом?
El Mac

28

Хоча існуючі відповіді дали рішення для вирішення питання та другої половини запитання, вони не дають відповіді на аспект самовідкриття першої половини запитання, виділений напівжирним шрифтом:

"Як я можу побачити, яка змінна спричиняє витрати пам'яті ...?"

Можливо, це не було настільки надійно 3 роки тому, але розділ " Профілі " для інструментів розробника Chrome зараз є досить потужним і багатим на функції. Команда Chrome має проникливу статтю про її використання, а отже, і про те, як працює збір сміття (GC) у javascript, що є основою цього питання.

Оскільки deleteв основному корінь прийнятої в даний час відповіді Йочай Акока, важливо пам’ятати, що робить видалення. Це не має значення, якщо не поєднувати з концепціями того, як працює GC, у наступних двох відповідях: якщо існує існуюче посилання на об’єкт, воно не очищається. Відповіді правильніші, але, мабуть, не настільки оцінені, тому що вони потребують більше продуму, ніж просто написання "видалити". Так, одним із можливих рішень може бути використання delete, але не має значення, чи є інше посилання на витік пам'яті.

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

Оскільки deleteтут вже було згадано, також може бути корисно надати ресурс Розуміння видалення . Хоча це не потрапляє в жодне фактичне рішення, яке насправді пов’язане зі збирачем сміття javascript.


9

Структуруйте свій код таким чином, щоб усі ваші тимчасові об'єкти знаходилися всередині закритих систем, а не в глобальному просторі імен / властивостях глобальних об'єктів і виходили за межі обсягу, коли ви закінчили з ними. Про все подбає GC.


1

Я стикався з такою проблемою і мав ідею просто змінити внутрішній HTML дітей проблемного об’єкта.

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

Здається брудно, але це врятувало мені життя, як це працює!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.