1. Механизм переработки мусора - GC
JavaScript имеет автоматический механизм сбора мусора (GC: сбор мусора), что означает, что среда выполнения отвечает за управление памятью, используемой во время выполнения кода.
Принцип: периодически (периодический) коллектор мусора (периодически) находит переменные, которые не используются, а затем освобождает их память.
Механизм сбора мусора JavaScript очень прост: узнайте переменные, которые больше не используются, а затем освободите память, которую он занимает. Тем не менее, этот процесс не является в режиме реального времени, потому что его накладные расходы относительно велики, поэтому сборщик мусора будет периодически выполнять с фиксированными интервалами времени .
Переменные, которые больше не используются, являются переменными, которые заканчивают жизненный цикл. Конечно, они могут быть только локальными переменными. Жизненный цикл глобальной переменной не закончится, пока браузер не удалит страницу. Локальные переменные существуют только во время выполнения функции, и в этом процессе соответствующее пространство будет выделено для локальных переменных в стеке или кучи для хранения их значений, а затем эти переменные используются в функции до конца функции. Однако из -за внутренних функций в закрытии внешние функции нельзя считать окончанием.
Давайте просто объясним код:
функция fn1 () {var obj = {name: 'hanzichi', возраст: 10};} function fn2 () {var obj = {name: 'hanzichi', возраст: 10}; вернуть obj;} var a = fn1 (); var b = fn2 ();Давайте посмотрим, как выполняется код. Во -первых, определены две функции, называемые FN1 и FN2. Когда FN1 называется, вход в среду FN1 откроет объект хранения памяти {имя: 'hanzichi', возраст: 10}. Когда вызов будет закончен и среда FN1 выйдет, блок памяти будет автоматически выпущен коллекционером мусора в двигателе JS; Во время процесса вызываемого FN2 возвращаемый объект указывает глобальную переменную B, поэтому блок памяти не будет выпущен.
Здесь возникает вопрос: какая переменная бесполезна? Следовательно, сборщик мусора должен отслеживать, какая переменная является бесполезной, и отмечают переменные, которые больше не полезны для восстановления своей памяти в будущем. Стратегии для бесполезных переменных, используемых для тега, могут отличаться в результате реализации, и обычно существует два способа сделать это: отметьте разрешение и подсчет ссылок. Подсчет цитат не очень распространен, чаще используется отметка.
2. Чистая марка
Наиболее часто используемым методом сбора мусора в JS является удаление отметка. Например, когда переменная входит в среду, объявляет переменную в функции, она отмечает переменную как «введите окружающую среду». Говоря по логике, память, занятая переменными, входящими в окружающую среду, не может быть выпущена, поскольку они могут использоваться, если поток выполнения входит в соответствующую среду. И когда переменная покидает окружающую среду, она помечена как «вне окружающей среды».
Function test () {var a = 10; // помечено, введите среду var b = 20; // помечен, введите среду} test (); // После исполнения A и B отмечены, покидают окружающую среду и переработаны.Когда коллекционер мусора работает, он отмечает все переменные, хранящиеся в памяти (конечно, можно использовать любой метод маркировки). Затем он удаляет теги (закрытия) переменных в среде и переменные, на которые ссылаются переменные в окружающей среде. Переменные, отмеченные после этого, будут рассматриваться как переменные, готовые к удалению, поскольку переменные в среде больше не могут получить доступ к этим переменным. Наконец, сборщик мусора завершает работу по очистке памяти, разрушая эти отмеченные значения и восстанавливая пространство памяти, которое они занимают.
До сих пор реализации JS IE, Firefox, Opera, Chrome и Safari используют стратегии сбора мусора для чистки мусора или аналогичные стратегии, но временные интервалы сбора мусора отличаются друг от друга.
3. Количество цитат
Значение ссылки состоит в том, чтобы отслеживать количество раз, когда ссылается на каждое значение. Когда переменная объявлена и значение типа ссылочного типа присваивается переменной, количество ссылок на это значение равно 1. Если одно и то же значение присваивается другой переменной, количество ссылок на значение увеличивается на 1. Наоборот, если переменная, содержащая ссылку на это значение, требует другого значения, число ссылок на это значение не уменьшается 1. Пространство, которое он занимает, может быть восстановлено. Таким образом, когда в следующий раз заработает коллектор мусора, он освобождает память, которая знакома с 0 ссылок.
function test () {var a = {}; // количество ссылок a равно 0 var b = a; // количество ссылок a равно 1 var c = a; // количество ссылок a IS 1, и количество ссылок a IS 1, и количество ссылок a IS 1, а количество ссылок a IS 2 var b = {}; // количество ссылок a IS 1, и количество ссылок A ранее 1}Netscape Navigator3 был первым браузером, который использовал стратегию подсчета ссылок, но вскоре он столкнулся с серьезной проблемой: круговые ссылки. Круглая ссылка относится к объекту, содержащему указатель на объект B, а объект B также содержит ссылку на объект A.
function fn () {var a = {}; var b = {}; A.pro = b; b.pro = a;} fn ();Время ссылки A и B выше составляет 2. После выполнения fn () оба объекта покинули среду. В режиме очистки отметки нет проблем. Однако в соответствии с стратегией подсчета ссылок, потому что временное отсчета A и B не 0, память не будет собираться коллекционером мусора. Если функция FN называется в больших количествах, возникнет утечка памяти. На IE7 и IE8 память резко возрастает.
Мы знаем, что некоторые объекты в IE не являются местными объектами JS. Например, объекты в DOM и BOM реализованы в форме объектов COM с использованием C ++, а механизм сбора мусора объектов COM принимает стратегию подсчета ссылок. Следовательно, даже если IE JS Engine принимает стратегию очистки тегов, объекты COM, доступные JS, все еще основаны на стратегии подсчета ссылок. Другими словами, пока в IE будут участвовать объекты COM, возникнет проблема круговых ссылок.
var element = document.getElementbyId ("some_element"); var myObject = new Object (); myObject.e = element; element.o = myObject;Этот пример создает круглую ссылку между элементом DOM и нативным объектом JS. Среди них переменная MyObject имеет атрибут с именем элемента, указывающий на объект элемента; и элемент переменной также имеет атрибут с именем o обратно для обозначения MyObject. Из -за этой круглой ссылки, даже если DOM в примере удален с страницы, он никогда не будет переработан.
Глядя на пример выше, некоторые студенты думали, что это было слишком слабым. Кто бы сделал такую скучную вещь? На самом деле, мы делаем это?
window.onload = function outterfunction () {var obj = document.getElementById ("element"); obj.onclick = function innerfunction () {};};Этот код, кажется, в порядке, но OBJ относится к Document.getElementByID («Элемент»), а метод OnClick Document.GetElementByID («элемент») будет ссылаться на немецкую переменную во внешней среде, что, естественно, также включает в себя OBJ. Разве это не очень скрыто?
Решение
Самый простой способ - это вручную не ссылаться на петлю, например, функция только сейчас может сделать это.
myobject.element = null; element.o = null;
window.onload = function outterfunction () {var obj = document.getElementById ("element"); obj.onclick = function innerfunction () {}; obj = null;};Установка переменной для NULL означает отключение соединения между переменной и значением, на которое она ранее ссылалась. Когда в следующий раз заканчивается сборщик мусора, эти значения удаляются, и память, которую они занимают, переработана.
Следует отметить, что IE9+ не имеет круговой ссылки, чтобы вызвать утечки памяти DOM. Может случиться так, что Microsoft оптимизировала его, или метод переработки DOM изменился.
4. Управление памятью
1. Когда будет запускается сбор мусора?
Коллекционер мусора периодически работает. Если выделенная память очень большая, работа по переработке будет очень сложной. Определение интервала времени сбора мусора становится вопросом, о котором стоит задуматься. Сбор мусора IE6 работает в соответствии с распределением памяти. Когда в окружающей среде есть какие -либо 256 переменных, 4096 объектов и 64 -километровых строк, сборщик мусора будет запускается. Это выглядит очень научно, и его не нужно на какое -то время называть. Иногда это ненужно. Разве не хорошо обращаться к такому спросу? Но если в окружающей среде так много переменных, а сценарии сейчас настолько сложны и нормальны, то результат заключается в том, что сборщик мусора всегда работает, поэтому браузер не может играть.
Microsoft внесла коррективы в IE7. Условия триггера больше не зафиксированы, но динамически модифицированы. Начальное значение такое же, как IE6. Если распределение памяти, собранное коллекционером мусора, составляет менее 15% от памяти, занятой программой, это означает, что большая часть памяти не может быть переработана. Условия триггера для сбора мусора слишком чувствительны. В это время удваивает уличные условия. Если собранная память выше 85%, это означает, что большая часть памяти должна быть очищена давно. В настоящее время условия спускового крючка уновлены. Это делает утилизацию мусора работать более функциями
2. Разумное решение GC
1) Основное решение GC двигателя JavaScript - (простой GC): отметьте и развернуть, т.е.:
2) дефекты GC
Как и другие языки, политика GC JavaScript не может избежать одной проблемы: когда GC прекратите реагировать на другие операции, что связано с соображениями безопасности. GC JavaScript составляет 100 мс или даже выше, что полезно для общих приложений, но для игр JS приложения, которые требуют высокой когерентности, являются проблемными. Это то, что должен оптимизировать новый двигатель: избегайте долгосрочной остановки, вызванной GC.
3) Стратегия оптимизации GC
Дядя Дэвид в основном ввел два решения для оптимизации, и это также наиболее важные два решения для оптимизации:
(1) Generation GC)
Это согласуется с идеей стратегии переработки Java. Цель состоит в том, чтобы различать «временные» и «постоянные» объекты; Уточнивайте больше областей «временного объекта» и менее «статей штатных объектов», уменьшайте объекты, которые необходимо пройти каждый раз, тем самым сокращая время, проведенное на GCS каждый раз. Как показано на картинке:
Здесь необходимо добавить, что для объекта штатного генерации существует дополнительная накладная плата: переносить его с молодого поколения в штатное поколение, и, если оно ссылается, то указание также необходимо изменить.
(2) Покрементный GC
Идея этого плана очень проста, которая состоит в том, чтобы «немного обращаться с каждым раз, немного разобраться в следующий раз и так далее». Как показано на картинке:
Хотя это решение занимает короткое время, оно имеет много перерывов, что приводит к проблеме частых переключений контекста.
Поскольку каждое решение имеет свои применимые сценарии и недостатки, в реальных приложениях решение будет выбран в соответствии с фактической ситуацией.
Например: когда соотношение (объекта/s) низкое, частота выполнения GC прерывается, а простой GC ниже; Если большое количество объектов «выживается» в течение длительного времени, преимущество обработки поколений не очень велика.
Вышеупомянутая статья полностью понимает механизм переработки мусора Javascirp, который я делюсь с вами. Я надеюсь, что это может дать вам ссылку, и я надеюсь, что вы сможете поддержать Wulin.com больше.