Skip to main content

Що робить збирач сміття (GC)?

1. Що робить збирач сміття (GC)

Збирач сміття (Garbage Collector) - це механізм JavaScript-рушія (наприклад, V8), який автоматично звільняє пам'ять, зайняту об'єктами, що стали недосяжними.

Тобто GC видаляє з пам'яті все, до чого більше немає посилань, щоб не витрачати ресурси і запобігти переповненню пам'яті.


2. Як це працює під капотом

JS-рушій керує пам'яттю так:

  1. Виділяє пам'ять під нові об'єкти:
javascript
let user = { name: 'Tim' }; // пам'ять виділена
  1. Якщо змінна перестає посилатися на об'єкт:
javascript
user = null; // старе посилання втрачено
  1. GC розуміє, що об'єкт { name: 'Tim' } недосяжний, і в найближчому циклі звільнить пам'ять.

3. Ключове поняття - "досяжність" (reachability)

У JS пам'ять очищується не вручну, а за принципом досяжності.

Досяжні (reachable) об'єкти:

  • глобальні змінні (window, global, globalThis);
  • локальні змінні в стеку (під час виконання функції);
  • об'єкти, на які посилаються інші досяжні об'єкти.

Недосяжні (unreachable):

  • об'єкти, на які немає посилань з досяжних місць.

Приклад:

javascript
let user = { name: 'Alice' }; let admin = user; // два посилання на один об'єкт user = null; // об'єкт все ще досяжний через admin admin = null; // тепер об'єкт недосяжний -> GC видалить

4. Приклад з ланцюжком посилань

javascript
function createUser() { const user = { name: 'Bob' }; const address = { city: 'Paris' }; user.addr = address; address.owner = user; // циклічне посилання! return user; } const person = createUser();

Тут об'єкт user посилається на address, і навпаки. Якщо потім:

javascript
person = null;

-> Обидва об'єкти стануть недосяжними (до них не можна дістатися з кореня) -> GC звільнить обидва, попри циклічні посилання.

JS-GC вміє визначати такі цикли.


5. Алгоритм роботи (на прикладі V8)

V8 (рушій Chrome, Node.js) використовує алгоритм "mark-and-sweep" (позначити і видалити):

  1. Mark (позначення): GC проходить від "кореневих" об'єктів (root: window, global, стек викликів) і позначає все, що досяжне.
  2. Sweep (очищення): Все, що не було позначено, видаляється з пам'яті.
  3. Compact (стиснення): Іноді пам'ять "ущільнюється", щоб звільнити місце.

У V8 також є:

  • Minor GC (Scavenge) - для "молодих" об'єктів (нові, живуть недовго);
  • Major GC (Mark-Sweep-Compact) - для "старих" (живуть довше, перевіряються рідше).

6. Як GC впливає на продуктивність

  • GC працює автоматично й асинхронно, але іноді викликає невеликі паузи (GC pause).
  • Чим більше "живих" об'єктів, тим довше триває цикл GC.
  • Витоки пам'яті заважають GC - він вважає "висячі" посилання живими.

Тому:

Оптимальний код = менше довгоживучих об'єктів + своєчасне "розривання" посилань.


7. Чого GC не робить

Не робитьЧому
Не очищує все одразуЩоб не заважати роботі програми
Не бачить "логічну непотрібність"Тільки відсутність посилань - не "інтелект"
Не керується вручнуНемає free() / delete, як у C++
Не чистить глобальні об'єктиВони завжди досяжні через window / globalThis

8. Типові помилки, що заважають GC

ПомилкаЩо відбувається
Глобальні зміннізалишаються досяжними назавжди
Таймери і слухачі без очищенняпосилання утримують замикання
DOM-посилання після видалення елементаGC не може видалити
Замикання з великими об'єктами"протікання" через область видимості

9. Як дивитися на GC і пам'ять

У браузері:

  • Chrome DevTools -> вкладка Memory -> "Heap snapshot"
  • Вкладка Performance -> Memory -> "Record"
  • Консоль: performance.memory.usedJSHeapSize

У Node.js:

  • --inspect, heapdump, clinic.js, process.memoryUsage()

10. Коротке резюме

ЩоОпис
GC (Garbage Collector)Механізм автоматичного звільнення пам'яті
ПринципВидаляє об'єкти, до яких не можна "дійти"
Головний алгоритмMark-and-sweep
Проблема витоківКоли об'єкт все ще досяжний, але не потрібен
РішенняРозривати посилання, чистити таймери і слухачі
ПлюсиПростота, безпека
МінусиПотенційні паузи і приховані витоки

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.