Що робить збирач сміття (GC)?
1. Що робить збирач сміття (GC)
Збирач сміття (Garbage Collector) - це механізм JavaScript-рушія (наприклад, V8), який автоматично звільняє пам'ять, зайняту об'єктами, що стали недосяжними.
Тобто GC видаляє з пам'яті все, до чого більше немає посилань, щоб не витрачати ресурси і запобігти переповненню пам'яті.
2. Як це працює під капотом
JS-рушій керує пам'яттю так:
- Виділяє пам'ять під нові об'єкти:
let user = { name: 'Tim' }; // пам'ять виділена- Якщо змінна перестає посилатися на об'єкт:
user = null; // старе посилання втрачено- GC розуміє, що об'єкт
{ name: 'Tim' }недосяжний, і в найближчому циклі звільнить пам'ять.
3. Ключове поняття - "досяжність" (reachability)
У JS пам'ять очищується не вручну, а за принципом досяжності.
Досяжні (reachable) об'єкти:
- глобальні змінні (
window,global,globalThis); - локальні змінні в стеку (під час виконання функції);
- об'єкти, на які посилаються інші досяжні об'єкти.
Недосяжні (unreachable):
- об'єкти, на які немає посилань з досяжних місць.
Приклад:
let user = { name: 'Alice' };
let admin = user; // два посилання на один об'єкт
user = null; // об'єкт все ще досяжний через admin
admin = null; // тепер об'єкт недосяжний -> GC видалить4. Приклад з ланцюжком посилань
function createUser() {
const user = { name: 'Bob' };
const address = { city: 'Paris' };
user.addr = address;
address.owner = user; // циклічне посилання!
return user;
}
const person = createUser();Тут об'єкт user посилається на address, і навпаки.
Якщо потім:
person = null;-> Обидва об'єкти стануть недосяжними (до них не можна дістатися з кореня) -> GC звільнить обидва, попри циклічні посилання.
JS-GC вміє визначати такі цикли.
5. Алгоритм роботи (на прикладі V8)
V8 (рушій Chrome, Node.js) використовує алгоритм "mark-and-sweep" (позначити і видалити):
- Mark (позначення):
GC проходить від "кореневих" об'єктів (root:
window,global, стек викликів) і позначає все, що досяжне. - Sweep (очищення): Все, що не було позначено, видаляється з пам'яті.
- 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 |
| Проблема витоків | Коли об'єкт все ще досяжний, але не потрібен |
| Рішення | Розривати посилання, чистити таймери і слухачі |
| Плюси | Простота, безпека |
| Мінуси | Потенційні паузи і приховані витоки |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.