Что такое сборка мусора в JavaScript? Что важно для веб-программиста, чтобы понять, что такое сборка мусора в JavaScript, чтобы лучше писать код?
297
Что такое сборка мусора в JavaScript? Что важно для веб-программиста, чтобы понять, что такое сборка мусора в JavaScript, чтобы лучше писать код?
Ответы:
Эрик Липперт написал подробное сообщение в блоге на эту тему некоторое время назад (дополнительно сравнивая его с VBScript ). Точнее, он написал о JScript , который является собственной реализацией ECMAScript от Microsoft, хотя и очень похож на JavaScript. Я полагаю, что вы можете предположить, что подавляющее большинство поведения будет таким же для движка JavaScript Internet Explorer. Конечно, реализация будет отличаться от браузера к браузеру, хотя я подозреваю, что вы могли бы взять ряд общих принципов и применить их к другим браузерам.
Цитируется с этой страницы:
Основная цель сборки мусора состоит в том, чтобы позволить программисту не беспокоиться об управлении памятью объектов, которые они создают и используют, хотя, конечно, иногда этого не избежать - всегда полезно иметь хотя бы приблизительное представление о том, как работает сборка мусора. ,
Историческая справка: более ранняя редакция ответа содержала неверную ссылку на
delete
оператора. В JavaScript оператор удаляет свойство из объекта , и полностью отличается в C / C ++.delete
delete
источник
delete
неправильно; например, в первом примере вместоdelete foo
, вы должны сначала удалить прослушиватель событий через,window.removeEventListener()
а затем использоватьfoo = null
для перезаписи переменной; в IEdelete window.foo
(но неdelete foo
) также работало бы, если бы оноfoo
было глобальным, но даже тогда это не сработало бы в FF или Operadelete
- это унарный оператор (выражение), а не оператор (то есть:)delete 0, delete 0, delete 3
. Это выглядит как выражение, когда оно выражено выражением выражения.Остерегайтесь циклических ссылок, когда задействованы объекты DOM:
Шаблоны утечки памяти в JavaScript
Имейте в виду, что память может быть восстановлена только тогда, когда нет активных ссылок на объект. Это распространенная ошибка с замыканиями и обработчиками событий, так как некоторые движки JS не проверяют, на какие переменные действительно ссылаются внутренние функции, а просто сохраняют все локальные переменные включающих функций.
Вот простой пример:
Наивная реализация JS не может собирать,
bigString
пока существует обработчик событий. Есть несколько способов решить эту проблему, например, установкаbigString = null
в концеinit()
(delete
не будет работать для локальных переменных и аргументов функций:delete
удаляет свойства из объектов, а объект переменной недоступен - ES5 в строгом режиме даже выдаст a,ReferenceError
если вы попытаетесь удалить локальную переменную!).Я рекомендую по возможности избегать ненужных замыканий, если вы заботитесь о потреблении памяти.
источник
Хорошая цитата взята из блога
Компонент DOM является «сборщиком мусора», как и компонент JScript, что означает, что если вы создадите объект в любом из компонентов, а затем потеряете отслеживание этого объекта, он в конечном итоге будет очищен.
Например:
Когда вы вызываете эту функцию, компонент JScript создает объект (с именем bigArray), который доступен внутри функции. Однако, как только функция возвращается, вы теряете отслеживание bigArray, потому что больше нет возможности ссылаться на него. Ну, компонент JScript понимает, что вы потеряли его, и поэтому bigArray очищается - его память освобождается. То же самое работает в компоненте DOM. Если вы говорите
document.createElement('div')
, или что-то подобное, то компонент DOM создает объект для вас. Как только вы как-то потеряете отслеживание этого объекта, компонент DOM очистит связанный.источник
Насколько я знаю, объекты JavaScript периодически собираются, когда на объект не остается ссылок. Это происходит автоматически, но если вы хотите узнать больше о том, как это работает, на уровне C ++ имеет смысл взглянуть на исходный код WebKit или V8.
Как правило, вам не нужно думать об этом, однако в старых браузерах, таких как IE 5.5 и более ранние версии IE 6, и, возможно, в текущих версиях, замыкания будут создавать циклические ссылки, которые, если их не проверять, в конечном итоге израсходуют память. В конкретном случае, когда я имею в виду замыкания, это было, когда вы добавили ссылку JavaScript на объект dom и объект на объект DOM, который ссылался на объект JavaScript. По сути, его никогда не удастся собрать, и в конечном итоге ОС станет нестабильной в тестовых приложениях, которые зацикливаются для создания сбоев. На практике эти утечки обычно невелики, но для поддержания чистоты кода необходимо удалить ссылку JavaScript на объект DOM.
Обычно хорошей идеей является использование ключевого слова delete для немедленной отмены ссылки на большие объекты, такие как данные JSON, которые вы получили назад и сделали с ними все, что вам нужно, особенно в разработке для мобильных устройств. Это приводит к следующей очистке GC, чтобы удалить этот объект и освободить его память.
источник
mark-and-sweep
алгоритмы стиля заботятся об этом .сборщик мусора (GC) - это форма автоматического управления памятью, удаляющая ненужные объекты.
любой процесс, связанный с памятью, выполните следующие действия:
1 - выделите необходимое пространство памяти
2 - сделать некоторую обработку
3 - освободить это пространство памяти
Есть два основных алгоритма, которые используются для определения того, какие объекты больше не нужны.
Сборка мусора с подсчетом ссылок : этот алгоритм сокращает определение «объект больше не нужен» до «у объекта нет ссылок на него», объект будет удален, если на него не будет ссылки
Алгоритм разметки и свипирования : соедините каждый объект с корневым источником. любой объект не соединяется с корнем или другим объектом. этот объект будет удален.
В настоящее время большинство современных браузеров используют второй алгоритм.
источник
Все движки JavaScript имеют свои собственные сборщики мусора, и они могут отличаться. В большинстве случаев вам не нужно иметь с ними дело, потому что они просто делают то, что должны делать.
Написание лучшего кода в основном зависит от того, насколько хорошо вы знаете принципы программирования, язык и особенности реализации.
источник
проверить это
В Javascript вы не заботитесь о выделении и освобождении памяти. Вся проблема требует интерпретатор Javascript. Утечки все еще возможны в Javascript, но они являются ошибками интерпретатора. Если вы заинтересованы в этой теме, вы можете прочитать больше на www.memorymanagement.org
источник
В Windows вы можете использовать Drip.exe, чтобы найти утечки памяти или проверить, работает ли ваша бесплатная программа mem.
Это действительно просто, просто введите URL веб-сайта, и вы увидите потребление памяти встроенным IE рендерером. Затем нажмите обновить, если память увеличивается, вы обнаружили утечку памяти где-то на веб-странице. Но это также очень полезно, чтобы увидеть, работают ли подпрограммы для освобождения памяти для IE.
источник
Ссылочные типы не сохраняют объект непосредственно в переменной, которой он назначен, поэтому переменная объекта в этом примере фактически не содержит экземпляр объекта. Вместо этого он содержит указатель (или ссылку) на место в памяти, где существует объект
если вы назначаете одну переменную другой, каждая переменная получает копию указателя, и обе по-прежнему ссылаются на один и тот же объект в памяти.
из принципов объектно-ориентированного JavaScript - НИКОЛАЙ С. ЗАКАС
источник