Найти тему

Сборка мусора в JavaScript

Многие виды данных в JavaScript, например, массивы, могут не иметь какого-то определённого размера. Это означает, что в ходе выполнения программы их размер может изменяться. Размер строк также может изменяться, и часто в большую сторону. Сложные и большие структуры данных могут занимать много места в памяти, поэтому желательно эту память освобождать сразу после того, как она становится не нужна.

При этом ссылочные переменные не содержат непосредственно данные, а лишь ссылки на них. Сами же данные хранятся в другом месте, а ссылочная переменная только указывает на местоположение этих данных.

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

Когда сценарий на JavaScript создаёт, например, строку, интерпретатор (обычно это браузер) должен выделить память для хранения этой строки. После того, как строка больше не нужна, выделенная ранее память должна быть освобождена (иначе она когда-нибудь закончится).

В “классических” языках программирования, таких как С++ и Паскаль, освобождение памяти выполняется вручную программистом. То есть программист должен позаботиться о том, чтобы вся выделенная память была освобождена. Из-за этого новички довольно часто допускают ошибки, поскольку либо освобождают память раньше времени, либо вообще забывают это сделать.

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

Если интерпретатор определяет, что объект недоступен (то есть больше нет способа получить ссылку на него), то он решает, что данный объект больше не нужен и занимаемая им память может быть освобождена.

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

Пример:

var hello = 'Привет'; //Выделили память для 'Привет'
var str = hello + ', МИР!!!'; //Выделили память для 'Привет, МИР!!!'
hello = str; //Перезаписали ссылку hello
//Здесь строки 'Привет' уже нет
alert(hello);

Здесь мы сначала определили ссылочную переменную hello (ссылочную, потому что в JavaScript все переменные, связанные со строками, являются ссылочными). Потом объявили тоже ссылочную переменную str и записали в память, на которую она ссылается, строку, на которую ссылается переменная hello и добавили к ней ещё несколько символов. Затем в переменную hello записали значение переменной str. Таким образом адрес, хранящийся в str, мы записали в переменную hello, и теперь она ссылается не на строку 'Привет', а на строку 'Привет, МИР!!!'.

Что происходит дальше? Строка 'Привет' на которую ссылалась переменная hello, и которая занимала какое-то место в памяти, больше не нужна, так как на это место в памяти больше не ссылается ни одна переменная (переменную hello мы перезаписали). Так что эту память можно освободить. Система это понимает, и освобождает память. Вот так и работает автоматическая сборка мусора.

На этом всё. Подписывайтесь на канал, чтобы ничего не пропустить.