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

В JavaScript память выделяется и освобождается автоматически. Он использует автоматическое управление памятью, известное как сборка мусора (GC).

Сборщик мусора отслеживает выделение памяти и определяет, когда выделенное пространство памяти не требуется, и возвращает его. Этот автоматический процесс работает по принципу приближения, поскольку он не может определить, нужна ли еще конкретная часть памяти.

Вывоз мусора

Чтобы справиться с этой проблемой, GC реализовал ограничение решения общей проблемы. Теперь мы обсудим некоторые важные темы, чтобы лучше понять основы GC.

использованная литература

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

В этом контексте понятие «объект» расширяется до чего-то более широкого, чем обычные объекты JavaScript, и также включает области видимости функций (или глобальную лексическую область видимости).

Подсчет ссылок

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

Пример

var x = { 
  a: {
    b: 2
  }
}; 
// 2 objects are created. One is referenced by the other as one of its properties.
// The other is referenced by virtue of being assigned to the 'x' variable.
// Obviously, none can be garbage-collected.

var y = x;      // The 'y' variable is the second thing that has a reference to the object.
x = 1;          // Now, the object that was originally in 'x' has a unique reference
                //   embodied by the 'y' variable.
var z = y.a;    // Reference to 'a' property of the object.
                //   This object now has 2 references: one as a property, 
                //   the other as the 'z' variable.
y = 'mozilla';  // The object that was originally in 'x' has now zero
                //   references to it. It can be garbage-collected.
                //   However its 'a' property is still referenced by 
                //   the 'z' variable, so it cannot be freed.
z = null;       // The 'a' property of the object originally in x 
                //   has zero references to it. It can be garbage collected.

Ограничение: Циклические ссылки

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

Посмотрите на пример, чтобы все стало ясно.

function f() {
  var x = {};
  var y = {};
  x.a = y;        // x references y
  y.a = x;        // y references x
  return 'sate sate sate';
}
f();

Алгоритм пометки и развертки

Этот алгоритм сводит определение «объект больше не нужен» к «объект недоступен».

Этот алгоритм предполагает знание набора объектов, называемых корнями . В JavaScript корень — это глобальный объект. Периодически сборщик мусора будет запускаться из этих корней, находить все объекты, на которые есть ссылки из этих корней, затем все объекты, на которые есть ссылки из этих корней, и т. д. Начиная с корней, сборщик мусора, таким образом, находит все доступные объектов и собрать все недоступные объекты.

Этот алгоритм является улучшением по сравнению с предыдущим, поскольку объект, имеющий нулевые ссылки, фактически недоступен. Обратное неверно, как мы видели с круговыми ссылками.

Циклы больше не проблема

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

Ограничение: Освобождение памяти вручную

Иногда ручное управление освобождением памяти намного проще.

По состоянию на 2019 год невозможно явно или программно запустить сборку мусора в JavaScript.

// Конец

Использованная литература:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management