Основная цель этой статьи - помочь читателям понять, как работает система управления памятью в JavaScript.
Я буду использовать сокращение, например GC, что означает Сборка мусора. Когда браузеры используют Javascript, им требуется любое место в памяти для хранения объектов, функций и всего остального. Давайте углубимся в то, как все будет работать в GC.
Сборщик мусора движка JavaScript ищет объекты, которые недоступны, а также удаляются из памяти.
Итак, я поделюсь примером ниже и покажу вам шаги, которые потребуются для работы с GC.
var number = 50; // allocates memory for a number var string = 'textual data'; // allocates memory for a string var object = {x: 10}; // allocates memory for an object var x= [10, null, 'abra']; // allocates memory for the array function f(x) { // allocates memory for a function return x * 2; }
В примере показано, как JavaScript выделяет память для переменных при их объявлении. Но когда память больше не нужна, выделенная память будет освобождена. GC находит память, больше не используемую приложением, и освобождает ее. Но главный вопрос в том, как GC находит память, которая больше не используется?
Базовый алгоритм для этого называется «отметка и очистка».
В алгоритме mark-and-sweep первый шаг - укорениться и запомнить их с помощью GC, а затем запомнить все ссылки из них. Затем посещает отмеченные объекты и запоминает их ссылки. Да, это сделано. Все посещенные объекты запоминаются, все объекты, кроме недоступных, удаляются сборщиком мусора.
var myObj = { a : 10 }
Теперь a
доступен из корня. Но если я установлю значение null
для этой переменной, объект будет недоступен и будет обработан сборщиком мусора.
Другой алгоритм называется «сборщик мусора с подсчетом ссылок».
Как это работает? Если в алгоритмах подсчета ссылок к объекту не прикреплена ссылка, он будет автоматически удален сборщиком мусора.
Давайте посмотрим на пример:
function foo() { var a = { myproperty: { y: 10 } }; var b = a.myproperty; b.myproperty = a; return 'textual data' } foo();
Если вы посмотрите код построчно, станет ясно, что a
имеет объект, в котором myproperty
содержит один объект. Поскольку a
имеет ссылку на объект, сборка мусора не требуется. Но позже случается проблема). Другая переменная b
также имеет ссылку на тот же объект, на который ссылается a ,
, потому что мы написали var b = a.myproperty .
, но позже a
был обновлен с помощью "textual data"
.
Здесь алгоритм подсчета ссылок не удаляет a
и b
из памяти после вызова функции, поскольку оба объекта ссылаются друг на друга. Таким образом, на b
не было ссылок при обновлении "textudal data"
. Поэтому может показаться, что объект, который он держал раньше, не имеет ссылок на него и может быть собран сборщиком мусора. Но идея была бы неправильной, если бы мы сказали, что a.myproperty
имеет ссылку на b.myproperty
. Следовательно, это не будет сборщиком мусора.
Спасибо за чтение.