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

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

Ответ 1

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 2

Остерегайтесь круговых ссылок, когда задействуются объекты 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, если вы попытаетесь удалить локальную переменную!).

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

Ответ 3

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

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

Например:

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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

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

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

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

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

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

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

Ответ 6

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

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

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

Ответ 7

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

проверить this

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

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

Ответ 8

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

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

Ответ 9

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

var object = new Object();

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

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

Two variables pointing to one object

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

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

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

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