Что такое сборка мусора в JavaScript? - PullRequest
290 голосов
/ 14 мая 2009

Что такое сборка мусора в JavaScript? Что важно для веб-программиста, чтобы понять, что такое сборка мусора в JavaScript, чтобы лучше писать код?

Ответы [ 9 ]

188 голосов
/ 14 мая 2009

Эрик Липперт написал подробное сообщение в блоге на эту тему некоторое время назад (дополнительно сравнивая его с VBScript ). Точнее, он написал о JScript , который является собственной реализацией ECMAScript от Microsoft, хотя и очень похож на JavaScript. Я полагаю, что вы можете предположить, что подавляющее большинство поведения будет одинаковым для движка JavaScript Internet Explorer. Конечно, реализация будет варьироваться от браузера к браузеру, хотя я подозреваю, что вы могли бы воспользоваться рядом общих принципов и применить их к другим браузерам.

Цитируется с этой страницы:

JScript использует не поколения сборщик мусора. Это работает так:

  • Каждая переменная, которая находится "в области видимости" называется "мусорщик". Падальщик может относиться к числу, объекту, Строка, что угодно. Мы поддерживаем список мусорщиков - переменные перемещены в список скава, когда они приходят в область видимости и из списка скав, когда они выходят за рамки.

  • Время от времени мусор Коллектор работает. Сначала это ставит «отметка» на каждом объекте, переменная, строка и т.д - вся память отслеживается по GC. (JScript использует VARIANT структура данных внутри и там много лишних неиспользованных битов в эта структура, поэтому мы просто установили один из их.)

  • Во-вторых, он очищает отметку на падальщики и переходное замыкание ссылок мусорщика. Так что если объект мусорщик ссылается на объект некавенгер тогда мы очищаем биты на некавенгере и на все, к чему это относится. (Я используя слово «закрытие» в другой смысл, чем в моем ранее пост.)

  • На данный момент мы знаем, что все память еще помечена выделена память, которая не может быть достигнута любым путь от любой переменной в области видимости. Все из этих объектов проинструктированы снести себя, что разрушает любые циклические ссылки.

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

Есть несколько особых моментов, о которых следует знать. На сайте разработчиков Apple есть некоторые рекомендации по этому вопросу. Оттуда два важных:

  • Использовать операторы удаления. Всякий раз, когда вы создаете объект с использованием нового оператора, связывайте его с оператором удаления. Это гарантирует, что вся память, связанная с объектом, включая имя его свойства, будет доступна для сборки мусора. Оператор удаления обсуждается более подробно в разделе «Освобождение объектов».
  • Используйте ключевое слово var. Любая переменная, созданная без ключевого слова var, создается в глобальной области и никогда не подходит для сборки мусора, что дает возможность утечки памяти.

Я полагаю, что эти практики должны применяться ко всем движкам JavaScript (в разных браузерах), хотя, поскольку это с сайта Apple, они могут быть несколько специфичными для Safari. (Может быть, кто-то может это уточнить?)

Надеюсь, это поможет.

52 голосов
/ 14 мая 2009

Остерегайтесь циклических ссылок, когда задействованы объекты DOM:

Шаблоны утечки памяти в JavaScript

Имейте в виду, что память может быть восстановлена ​​только тогда, когда нет активных ссылок на объект. Это распространенная ошибка с замыканиями и обработчиками событий, поскольку некоторые движки JS не проверяют, на какие переменные действительно ссылаются внутренние функции, а просто сохраняют все локальные переменные включающих функций.

Вот простой пример:

function init() {
    var bigString = new Array(1000).join('xxx');
    var foo = document.getElementById('foo');
    foo.onclick = function() {
        // this might create a closure over `bigString`,
        // even if `bigString` isn't referenced anywhere!
    };
}

Наивная реализация JS не может собирать bigString, пока существует обработчик событий. Есть несколько способов решения этой проблемы, например, установка bigString = null в конце init() (delete не будет работать для локальных переменных и аргументов функций: delete удаляет свойства из объектов, а объект переменной недоступен - ES5 в строгом режиме даже выдаст ReferenceError, если вы попытаетесь удалить локальную переменную!).

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

15 голосов
/ 14 мая 2009

Хорошая цитата взята из блога

Компонент DOM является "сборщиком мусора", как и компонент JScript, что означает, что если вы создадите объект в любом из компонентов, а затем потеряете отслеживание этого объекта, он в конечном итоге будет очищен.

Например:

function makeABigObject() {
var bigArray = new Array(20000);
}

Когда вы вызываете эту функцию, компонент JScript создает объект (с именем bigArray), который доступен внутри функции. Однако, как только функция возвращается, вы «теряете след» bigArray, потому что больше нет возможности ссылаться на него. Ну, компонент JScript понимает, что вы потеряли его, и поэтому bigArray очищается - его память освобождается. То же самое работает в компоненте DOM. Если вы скажете document.createElement('div') или что-то подобное, компонент DOM создаст для вас объект. Как только вы как-то потеряете отслеживание этого объекта, компонент DOM очистит связанный.

13 голосов
/ 14 мая 2009

Насколько я знаю, объекты JavaScript периодически собираются в мусор, если на объект не осталось ссылок. Это происходит автоматически, но если вы хотите узнать больше о том, как это работает, на уровне C ++ имеет смысл взглянуть на исходный код WebKit или V8

Как правило, вам не нужно думать об этом, однако в старых браузерах, таких как IE 5.5 и более ранние версии IE 6, и, возможно, в текущих версиях, замыкания создают циклические ссылки, которые, если их не проверять, приводят к потере памяти. В конкретном случае, когда я имею в виду замыкания, это было, когда вы добавили ссылку JavaScript на объект dom и объект на объект DOM, который ссылался на объект JavaScript. По сути, его никогда не удастся собрать, что в конечном итоге приведет к нестабильной работе ОС в тестовых приложениях, которые зацикливаются для создания сбоев. На практике эти утечки обычно невелики, но для поддержания чистоты кода необходимо удалить ссылку JavaScript на объект DOM.

Обычно хорошей идеей является использование ключевого слова delete для немедленной отмены ссылки на большие объекты, такие как данные JSON, которые вы получили обратно и сделали с ними все, что вам нужно, особенно в разработке для мобильных устройств. Это приводит к следующей очистке ГХ для удаления этого объекта и освобождения его памяти.

6 голосов
/ 05 апреля 2015

сборщик мусора (GC) - это форма автоматического управления памятью путем удаления ненужных объектов.

любой процесс имеет дело с памятью, выполните следующие действия:

1 - выделите необходимое пространство памяти

2 - выполнить обработку

3 - освободить это пространство памяти

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

Сборка мусора с подсчетом ссылок : этот алгоритм сокращает определение «объект больше не нужен» до «объект не имеет другого ссылающегося на него объекта», объект будет удален, если нет ссылочной точки к этому

Алгоритм разметки и развертки : подключить каждый объект к корневому источнику. любой объект не соединяется с корнем или другим объектом. этот объект будет удален.

В настоящее время большинство современных браузеров используют второй алгоритм.

4 голосов
/ 14 мая 2009

"В информатике сборщик мусора (GC) - это форма автоматического управления памятью. Сборщик мусора, или просто сборщик, пытается вернуть мусор или память, используемую объектами, которые никогда не будут доступны или изменены в приложении. . "

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

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

1 голос
/ 06 февраля 2012

В Windows вы можете использовать Drip.exe , чтобы найти утечки памяти или проверить, работает ли ваша бесплатная программа mem.

Это действительно просто, просто введите URL-адрес веб-сайта, и вы увидите потребление памяти встроенным IE рендерером. Затем нажмите обновить, если память увеличивается, вы обнаружили утечку памяти где-то на веб-странице. Но это также очень полезно, чтобы увидеть, работают ли подпрограммы для освобождения памяти для IE.

1 голос
/ 14 мая 2009

Что такое сборка мусора в JavaScript?

чек это

Что важно для веб-программиста, чтобы понять о сборке мусора JavaScript, для того, чтобы написать лучший код?

В Javascript вы не заботитесь о распределении и освобождении памяти. Вся проблема требует интерпретатор Javascript. Утечки все еще возможны в Javascript, но они являются ошибками интерпретатора. Если вы заинтересованы в этой теме, вы можете прочитать больше в www.memorymanagement.org

0 голосов
/ 09 октября 2018

Типы ссылок не сохраняют объект непосредственно в переменной которой он назначен, поэтому переменная объекта в этом примере на самом деле не содержать экземпляр объекта. Вместо этого он содержит указатель (или ссылку) на место в памяти, где существует объект

var object = new Object();

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

var object1 = new Object();
var object2 = object1;

Two variables pointing to one object

JavaScript - это язык для сбора мусора , поэтому вам не нужно беспокоиться о распределении памяти при использовании ссылочных типов. Тем не мение, лучше разыменовать объекты, которые вам больше не нужны, чтобы мусор коллекционер может освободить эту память. Лучший способ сделать это - установить переменная объекта к нулю.

var object1 = new Object();
// do something
object1 = null; // dereference

Разыменование объектов особенно важно в очень больших приложениях, которые используют миллионы объектов.

из Принципов объектно-ориентированного JavaScript - НИКОЛАЙ С. ЗАКАС

...