Stack va Heap
JavaScript'da stack va heap xotira tuzilmalari, primitive va reference turlari o'rtasidagi farq, call stack, stack overflow va memory leak tushunchalarini o'rganing.
10-dars
π§ Stack va Heap nima?
JavaScript'da hamma narsa xotirada saqlanadi. Asosiy ikkita joy bor:
- Stack β tezkor, tartibli xotira
- Heap β katta, moslashuvchan xotira
Ularni tushunish:
- Primitive vs Reference farqini
===xatti-harakati- Memory leak va stack overflow
ni to'g'ri tushunishga yordam beradi.
1οΈβ£ Stack nima?
Stack β bu tezkor xotira joyi bo'lib, u yerda:
- Primitive qiymatlar:
number,string,boolean,null,undefined,symbol,bigint - Reference'lar: object/array/function'ga bo'lgan manzil (adres)
- Function chaqirilganda yaratiladigan execution context (call frame) ma'lumotlari
saqlanadi.
Stack LIFO bo'yicha ishlaydi
Stack β LIFO: Last In, First Out (oxiri kirgan β birinchi chiqadi).
function a() {
b();
}
function b() {
c();
}
function c() {}
a();
Call stack ketma-ketligi:
a()chaqiladi β stack:aa()ichidab()chaqiladi β stack:a β bb()ichidac()chaqiladi β stack:a β b β cctugaydi β stackdan chiqadi β qoladia β bbtugaydi β chiqadi β qoladiaatugaydi β stack bo'sh
β Stack juda tez, chunki:
- Tartibli
- Har doim faqat tepadan (oxiridan) qo'shadi va olib tashlaydi
2οΈβ£ Heap nima?
Heap β bu katta, moslashuvchan βomborβ xotira. U yerda:
ObjectArrayFunction(object sifatida)classinstance'lar- Katta strukturali data
saqlanadi.
Heap'da joylashuv:
- Tartibli emas
- βQayerdan bo'sh joy topsa, o'sha yergaβ joylashtiriladi
β Heap:
- Katta, moslashuvchan
β Stack'dan sekinroq, chunki:
- Joy ajratish (allocation)
- Garbage Collector (GC) ishlashi
bor.
3οΈβ£ Primitive vs Reference β eng muhim farq
Primitive turlar β Stack'da (qiymat nusxalanadi)
let a = 5;
let b = a;
b = 10;
console.log(a); // 5
console.log(b); // 10
Nega a o'zgarmadi?
aning qiymati (5) stack'da turadib = abo'lganda β qiymat nusxalanadibo'zgartirilsa β buaga ta'sir qilmaydi
Reference turlar β Heap + Stack (manzil nusxalanadi)
let obj1 = { x: 1 };
let obj2 = obj1;
obj2.x = 99;
console.log(obj1.x); // 99
console.log(obj2.x); // 99
Nega ikkalasi ham 99?
{ x: 1 }β Heap'da saqlanadiobj1β Stack'da, ichida heap'dagi obyektga manzil (reference) borobj2 = obj1β reference nusxalanadi (bitta manzilga ishora qiladi)
Shuning uchun obj1 va obj2 bitta obyektni ko'rsatadi.
Buni chizma qilib tasavvur qilamiz
let user = { name: "Ali" };
Stack:
userβ manzil:0xA12
Heap:
0xA12β{ name: "Ali" }
Stack'da obyektning o'zi yo'q β faqat adres (manzil) bor.
4οΈβ£ Nega bu farq juda muhim?
1) === reference'larda boshqacha ishlaydi
[] === [] // false
{} === {} // false
Nega?
- Heap'da ikkita boshqa obyekt
- Demak ikkita boshqa adres
const a = [];
const b = a;
console.log(a === b); // true
Bu yerda:
avabbir xil manzilni ko'rsatadi- Shuning uchun
===true
2) Function ichidagi local variable'lar qayerda?
function test() {
let n = 1; // primitive β qiymat stack'da
let arr = [1, 2]; // arr reference β stack, [1, 2] β heap
}
- Har bir function chaqirilganda yangi call frame stack'ga qo'shiladi
- Shu frame ichida local o'zgaruvchilar saqlanadi
5οΈβ£ Stack vs Heap β qisqa taqqoslash
| Narsa | Stack | Heap |
|---|---|---|
| Saqlanadigan data | Primitive qiymatlar, reference adreslar, call frames | Object / Array / Function / katta strukturalar |
| Tezlik | Juda tez | Nisbatan sekinroq |
| Tartib | LIFO (tartibli) | Tartibsiz (allocation bo'yicha) |
| O'lcham | Kichikroq / limitli | Kattaroq |
| Tozalash | Funksiya tugaganda avtomatik chiqib ketadi | Garbage Collector orqali |
| Tipik xatolik | Stack overflow | Memory leak / GC bosimi |
6οΈβ£ Stack overflow (chuqur recursion)
function f() {
f();
}
f(); // RangeError: Maximum call stack size exceeded
Nega?
- Har chaqirilganda
fuchun yangi call frame stack'ga qo'shiladi - Stack cheksiz emas
- Ma'lum bir chuqurlikdan keyin "Maximum call stack size exceeded" xatosi chiqadi
Bu β stack overflow.
7οΈβ£ Memory leak (heap to'lib borishi)
Agar sen heap'dagi obyektlarga reference'ni ushlab tursang, Garbage Collector ularni o'chirolmaydi.
const globalArray = [];
function addData() {
const bigData = new Array(1000000).fill("salom");
globalArray.push(bigData);
}
setInterval(addData, 1000);
Bu kod:
- Har sekund yangi katta massiv yaratadi
- Uni globalArray ichiga qo'shadi
- Unga reference doim bor β GC o'chira olmaydi
- Xotira tobora ko'payib boradi β memory leak
β Memory leakdan qochish uchun:
- Kerak bo'lmagan reference'larni o'chirish
- Global state'ni keraksiz ko'paytirmaslik
- Uzoq yashaydigan obyektlarga ehtiyot bo'lish kerak
8οΈβ£ Amaliy misollar β Primitive vs Reference
Primitive β mustaqil nusxa
let x = 10;
let y = x;
y++;
console.log(x); // 10
console.log(y); // 11
Reference β bir obyekt, bir nechta reference
let user1 = { name: "Ali" };
let user2 = user1;
user2.name = "Vali";
console.log(user1.name); // "Vali"
console.log(user2.name); // "Vali"
Agar yangi obyekt kerak bo'lsa:
const user1 = { name: "Ali" };
const user2 = { ...user1 }; // shallow copy
user2.name = "Vali";
console.log(user1.name); // "Ali"
console.log(user2.name); // "Vali"
π Xulosa
- Stack β tezkor, tartibli, LIFO; primitive qiymatlar, reference adreslar va call frame'lar saqlanadi
- Heap β katta, moslashuvchan; object/array/function va katta strukturalar saqlanadi
- Primitive'lar nusxalanadi β o'zgarishlar boshqa o'zgaruvchilarga ta'sir qilmaydi
- Reference'larda adres nusxalanadi β bir obyektni bir nechta o'zgaruvchi ko'rsatishi mumkin
[] === []false, chunki manzillar boshqacha; bir xil reference bo'lsa β true- Stack overflow β juda chuqur recursion yoki cheksiz call stack
- Memory leak β heap'dagi obyektlarga reference tushmay qolmaguncha GC o'chira olmaydi
Bu mavzuni yaxshi tushunsang, keyingi darslarda:
- Closure
- Scope
- Garbage Collection
ni tushunish osonroq bo'ladi.