Как устроена память в JavaScript (memory heap, memory stack)?angular-5

1. Call Stack

Стек — это LIFO-структура (Last In, First Out), где хранятся примитивы и ссылки на объекты в Heap.

Как работает:

  • Каждый вызов функции создает фрейм в стеке.
  • При завершении функции фрейм удаляется.
  • Пример:
    function foo() {
      let x = 10; // Примитив хранится в стеке
      bar();
    }
    
    function bar() {
      let y = 20; // Еще один фрейм
    }
    
    foo(); // Стек: [foo] -> [foo, bar] -> [foo] -> []
    

Особенности:

  • Стек имеет ограниченный размер (при переполнении — RangeError: Maximum call stack size exceeded).
  • Быстрый доступ, но нельзя удалить элементы из середины.

2. Memory Heap

Динамическая область памяти для хранения объектов (ссылочные типы).

Как работает:

  • Объекты создаются в куче, а в стеке хранятся ссылки на них.
  • Пример:
    let user = { name: "Alice" }; // Объект в Heap, ссылка `user` — в стеке
    let arr = [1, 2, 3]; // Аналогично
    

Проблемы:

  • Утечки памяти: если ссылка на объект остается, но не используется.
    let button = document.getElementById('btn');
    button.onclick = () => console.log("Clicked"); // Утечка, если кнопка удалена из DOM
    

3. Управление памятью: Garbage Collection

JavaScript использует автоматическую сборку мусора (например, алгоритм Mark-and-Sweep):

  1. Mark: Обходит все достижимые объекты (от корневых ссылок).
  2. Sweep: Удаляет недостижимые.

Пример циклической ссылки:

let obj1 = { ref: null };
let obj2 = { ref: null };
obj1.ref = obj2; // Ссылка друг на друга
obj2.ref = obj1;
// Если убрать внешние ссылки, сборщик мусора удалит их (современные алгоритмы справляются с циклами)

4. Оптимизации в Angular

  • Отписка от Observables:
    ngOnDestroy() {
      this.subscription.unsubscribe(); // Иначе утечка памяти
    }
    
  • Использование OnPush Change Detection: уменьшает количество проверок объектов.
  • Очистка событий:
    @HostListener('click', ['$event'])
    onClick(event: Event) { ... } // Angular автоматически управляет подпиской
    

Резюмируем

  1. Стек:
    • Быстрый доступ.
    • Хранит примитивы и ссылки.
    • Ограничен по размеру.
  2. Куча:
    • Хранит объекты.
    • Динамическое выделение памяти.
    • Риск утечек.
  3. Garbage Collection:
    • Автоматически удаляет недостижимые объекты.
    • В Angular важно вручную чистить подписки и DOM-ссылки.

P.S. Для анализа памяти используйте Chrome DevTools → Memory Snapshot.