Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Heap і stack у Node.js». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Stack** - швидка LIFO-структура для примітивів, посилань і контексту виклику функцій; **heap** - динамічна область для об'єктів, масивів, функцій і замикань, якою керує збирач сміття. **Ключове:** глибока рекурсія переповнює stack (Stack Overflow), а забуті посилання на об'єкти в heap спричиняють витоки пам'яті.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Що таке пам'ять процесу Node.js Коли ти запускаєш застосунок Node.js, система виділяє йому область пам'яті. Ця пам'ять ділиться на дві головні частини: | Область | Призначення | |---|---| | **Stack (стек)** | Зберігає *контекст виконання* - функції, змінні примітивних типів і адреси повернення. | | **Heap (куча)** | Зберігає *об'єкти, масиви, функції, замикання* - усе, що створюється динамічно. | Обидві області керуються рушієм **V8**, вбудованим у Node.js. ## 2. Stack (стек) Стек - це **впорядкована структура LIFO (Last In, First Out)**. Вона використовується для зберігання **контексту виконання функцій**. ### Приклад: ```javascript function a() { const x = 10; b(); } function b() { const y = 20; console.log(y); } a(); ``` ### Що відбувається: 1. Виклик `a()` → створюється **frame (кадр)** у стеку: ```javascript [ a() ] ``` 2. `a()` викликає `b()` → новий кадр кладеться зверху: ```javascript [ b() ] [ a() ] ``` 3. Коли `b()` завершує роботу - її кадр видаляється: ```javascript [ a() ] ``` 4. Коли `a()` завершується - стек стає порожнім. Примітивні значення (`number`, `boolean`, `undefined`, `null`, `symbol`, `bigint`) і посилання на об'єкти зберігаються саме в стеку. ## 3. Heap (куча) **Heap** - це **динамічна область пам'яті**, де зберігаються **об'єкти, масиви, функції, замикання, класи** - усе, що має змінний розмір і живе довше, ніж одна функція. ### Приклад: ```javascript function createUser() { const user = { name: 'Tim', age: 25 }; return user; } const u = createUser(); ``` - У стеку зберігається посилання на `user`. - Сам об'єкт `{ name: 'Tim', age: 25 }` зберігається в **купі (heap)**. Керує кучею **Garbage Collector (GC)**: коли на об'єкт більше немає посилань, GC звільняє пам'ять. ## 4. Візуально: ```javascript Stack: (швидкий, малий, LIFO) ┌──────────────────────┐ │ main() │ │ ├─ userRef → (heap) │ │ └─ total = 42 │ └──────────────────────┘ Heap: (великий, динамічний) ┌────────────────────────────────────────┐ │ { name: "Tim", age: 25 } │ │ [1, 2, 3, 4, 5] │ │ function user() {...} │ └────────────────────────────────────────┘ ``` ## 5. Відмінності stack vs heap | Критерій | Stack | Heap | |---|---|---| | **Тип даних** | Примітиви, посилання, контекст виклику | Об'єкти, масиви, функції | | **Розмір** | Малий і фіксований | Великий і динамічний | | **Швидкість доступу** | Дуже висока | Повільніше | | **Життєвий цикл** | Автоматично звільняється при виході з функції | Керується збирачем сміття | | **Керування** | Послідовне (LIFO) | Невпорядковане (GC вирішує, що видаляти) | | **Помилки** | Переповнення стека (Stack Overflow) | Витік пам'яті (Memory Leak) | ## 6. Stack Overflow Якщо рекурсія чи виклики функцій не закінчуються, стек переповнюється: ```javascript function recurse() { recurse(); } recurse(); // RangeError: Maximum call stack size exceeded ``` Кожен виклик функції додає фрейм у стек → при надто глибокій рекурсії стек переповнюється. ## 7. Garbage Collection і heap V8 автоматично звільняє пам'ять із heap, коли об'єкт **стає недосяжним** (на нього немає посилань): ```javascript let user = { name: 'Tim' }; user = null; // тепер об'єкт недосяжний → GC звільнить пам'ять ``` V8 ділить кучу на дві частини: - **New Space** - для нових об'єктів (швидка, очищається часто); - **Old Space** - для "довгоживучих" об'єктів (очищається рідше, але складніше). ## 8. Продуктивність - **Операції зі stack** (наприклад, арифметика, виклики функцій) дуже швидкі. - **Операції з heap** повільніші - потрібно виділяти пам'ять, звертатися по посиланнях, працювати з GC. Тому **менше створювати тимчасові об'єкти** й **перевикористовувати структури даних** - це оптимізація коду для Node.js. ## 9. Приклад поєднання stack і heap ```javascript function addUser() { const id = 1; // stack const user = { id, name: 'Tim' }; // heap return user; } const u = addUser(); // u (stack) → {id: 1, name: 'Tim'} (heap) ``` - `id` (примітив) зберігається у стеку; - об'єкт `user` зберігається в купі; - змінна `u` у стеку містить посилання на об'єкт у купі. ## 10. Резюме | Область | Опис | |---|---| | **Stack (стек)** | Швидка область пам'яті для зберігання викликів функцій і примітивів. Керується автоматично. | | **Heap (куча)** | Динамічна область пам'яті для зберігання об'єктів, масивів і функцій. Керується збирачем сміття. | | **Зв'язок** | Стек зберігає посилання на об'єкти, що лежать у купі. | | **Помилки** | Stack overflow - при глибокій рекурсії. Memory leak - при утриманні непотрібних посилань. |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.