Жизненный цикл и выделение памяти в JS

343
16 мая 2017, 04:34

В объектно ориентированных языках по типу Java/C# память при создании выделяется: для примитивов(в stack), для объектов(в heap). Соответственно жизненный цикл у таких объектов разный. Объясните пожалуйста, распределение памяти и жизненный цикл у объектов и примитивов в JS реализованы так же?

Answer 1

Главной концепцией управления памятью в JavaScript является принцип достижимости.

  1. Определённое множество значений считается достижимым изначально, в частности:

    Значения, ссылки на которые содержатся в стеке вызова, то есть – все локальные переменные и параметры функций, которые в настоящий момент выполняются или находятся в ожидании окончания вложенного вызова.

    Все глобальные переменные.

  2. Любое другое значение сохраняется в памяти лишь до тех пор, пока доступно из корня по ссылке или цепочке ссылок.

Для очистки памяти от недостижимых значений в браузерах используется автоматический Сборщик мусора, встроенный в интерпретатор, который наблюдает за объектами и время от времени удаляет недостижимые.

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

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

Есть одно упрощение для работы с памятью: «значение остаётся в памяти, пока на него есть хотя бы одна ссылка».

Но такое упрощение будет верным лишь в одну сторону.

Верно – в том плане, что если ссылок на значение нет, то память из-под него очищается.

 Например, была создана ссылка в переменной, и эту переменную тут же перезаписали:
    let user = {
        name: "Вася"
    };
    user = null;

Теперь объект { name: "Вася" } более недоступен. Память будет освобождена.

Неверно – в другую сторону: наличие ссылки не гарантирует, что значение останется в памяти.

Такая ситуация возникает с объектами, которые ссылаются друг на друга:
let vasya = {};
let petya = {};
vasya.friend = petya;
petya.friend = vasya;
vasya = petya = null;

Несмотря на то, что на объекты vasya, petya ссылаются друг на друга через ссылку friend, то есть можно сказать, что на каждый из них есть ссылка, последняя строка делает эти объекты в совокупности недостижимыми.

Поэтому они будут удалены из памяти.

Здесь как раз и играет роль «достижимость» – оба этих объекта становятся недостижимы из корней, в первую очередь, из глобальной области, стека.

Сборщик мусора отслеживает такие ситуации и очищает память. Подробнее

Если есть время можно ознакомиться с некоторыми главами этой книги

READ ALSO
Появляются лишние данные как поправить?

Появляются лишние данные как поправить?

Нужна помощь! Есть поля карточки клиентаНажимаешь на нужную информацию вместо нее подставляется input и можно редактировать

312
Как зациклить анимацию (setInterval)

Как зациклить анимацию (setInterval)

Пишу себе велосипед, кубик должен бесконечно двигаться вправо и возвращатьсяПроисходит только 1 итерация

363
Не фиксировать определенный option в select

Не фиксировать определенный option в select

ЗдравствуйтеМой селект обрабатывается js

252