Heap vs Stack in JavaScript Memory
JavaScript-ի շարժիչը (օր.՝ V8) հիշողությունը բաժանում է երկու հիմնական հատվածի՝
- Call Stack — պահում է գործառույթների execution context-ները և primitive տվյալները։
- Heap — պահում է reference տեսակի օբյեկտները, ֆունկցիաները և array-ները։
Երբ փոփոխական ես հայտարարում՝ հիշողության տարբեր հատվածներ են օգտագործվում՝ կախված տվյալների տիպից։
// Stack - primitive types
let age = 30;
let isOnline = true;
// Heap - reference types
let user = {
name: "Ani",
age: 25
};
Երբ primitive փոփոխական փոխանցում ես ֆունկցիային՝ դա փոխանցվում է ըստ արժեքի (by value), իսկ օբյեկտը՝ ըստ հղման (by reference)։
function updateAge(a) {
a = 40;
}
let myAge = 30;
updateAge(myAge);
console.log(myAge); // 30 - primitive => value copy
function updateUser(obj) {
obj.age = 40;
}
let person = { age: 30 };
updateUser(person);
console.log(person.age); // 40 - reference => direct modify
Heap vs Stack-ը հասկանալու առավելությունները.
- Օգնում է հասկանալ փոփոխականների պահվածքը ֆունկցիաներում
- Անհրաժեշտ է performant կոդ գրելու համար
Հիշողության արդյունավետ կառավարման խորհուրդներ
Քանի որ JavaScript-ն ավտոմատ է կառավարում հիշողությունը, մենք չենք գրում free() կամ delete, ինչպես C-ում, սակայն մենք կարող ենք նպաստել արդյունավետությանը՝
- Օգտագործիր
constայնտեղ, որտեղ փոփոխություն պետք չէ - Փակիր timers, intervals, sockets, observers երբ այլևս պետք չեն
- Օգտագործիր WeakMap և WeakSet, եթե պահում ես օբյեկտներ՝ առանց խոչընդոտելու GC-ին
- Հեռացրու DOM event listener-ները՝ componentWillUnmount կամ useEffect-ի cleanup-ում
// WeakMap – թույլ հղում, GC կարող է ազատել օբյեկտը
let cache = new WeakMap();
function process(user) {
if (!cache.has(user)) {
cache.set(user, computeHeavy(user));
}
return cache.get(user);
}
Ինչու՞ օգտագործել WeakMap/WeakSet-ը:
- Ոչ թե "պահում" են օբյեկտները, այլ թույլ են տալիս GC-ին ջնջել դրանք, երբ ոչ մի այլ հղում չկա։
- Օգտակար են cache-երում, observer pattern-ում, metadata attach-ում։