Garbage Collection — xotira qanday tozalanadi, Memory Leak
Muammodan boshlaylik
Siz uzoq vaqt ishlaydigan veb ilova yozdingiz — admin panel, dashboard. Boshida tez ishlaydi. 30 daqiqadan keyin sekinlashadi. Bir soatdan keyin brauzer "sahifa ko'p xotira sarflayapti" deydi.
Kod to'g'ri ishlaydi. Xato chiqmaydi. Lekin xotira ozayib boradi. Bu — Memory Leak (xotira oqishi).
Memory Leak ni tushunish uchun — JavaScript xotirani qanday boshqarishini tushunish kerak.
JavaScript xotirani qanday boshqaradi?
JavaScript avtomatik xotira boshqaruviga ega. Siz malloc/free (C dagi kabi) yozmasiz. JavaScript o'zi xotira ajratadi va kerak bo'lmaganda tozalaydi.
Bu tozalash jarayoni — Garbage Collection (axlat yig'ish).
Hayotiy o'xshatma
Mehmonxona xodimi. Mehmon ketgandan keyin — xona tozalanadi, yangi mehmon uchun tayyorlanadi. Lekin xodim faqat haqiqatan bo'sh xonalarni tozalaydi. Agar biror mehmonning jihozi xonada qolgan bo'lsa — "hali band" deb hisoblanadi.
Garbage Collector — o'sha xodim. Ob'ektga reference qolmagan bo'lsa — "bo'sh" deb tozalaydi.
Reachability — yetib borish mumkinmi?
Garbage Collector bir savolni beradi: "Ushbu ob'ektga yetib borish mumkinmi?"
"Yetib borish mumkin" — bu global o'zgaruvchilar, joriy chaqiruv steki, yoki ulardan zanjirlanib borilishi mumkin ob'ektlar.
let foydalanuvchi = { ism: "Jasur" };
// { ism: "Jasur" } — yetib borish mumkin, foydalanuvchi orqali
foydalanuvchi = null;
// { ism: "Jasur" } — endi yetib borib bo'lmaydi, reference yo'q
// Garbage Collector tozalaydi
Ikki ob'ekt bir-biriga reference ushlab tursa ham — agar tashqaridan yetib borish mumkin bo'lmasa, tozalanadi:
function yaratishVaYo_qotish() {
const a = { nomi: "A" };
const b = { nomi: "B" };
a.hamkor = b; // a → b
b.hamkor = a; // b → a — bir-biriga reference
// Funksiya tugaydi — a va b lokal o'zgaruvchilar yo'qoladi
// Tashqaridan yetib bo'lmaydi — ikkisi ham tozalanadi
}
Memory Leak — xotira tozalanmaydi
Memory Leak — ob'ektlarga reference saqlanib qoladi, lekin ular endi kerak emas. Garbage Collector tozalay olmaydi — chunki "yetib borish mumkin".
Eng ko'p uchraydigan hollar
1. Global o'zgaruvchi — intentional emas:
function hisobla() {
natija = []; // ← `let`/`const` yo'q — global o'zgaruvchi yaratildi!
for (let i = 0; i < 100000; i++) {
natija.push({ id: i, ma'lumot: new Array(1000).fill("x") });
}
}
hisobla();
// natija — global, hech qachon tozalanmaydi
Har funksiya chaqiruvida massiv kattalashib boradi. "use strict" bu xatoni oldini oladi.
2. Unutilgan interval:
function boshlash() {
const katta_massiv = new Array(100000).fill("x");
setInterval(function() {
console.log(katta_massiv.length); // ← katta_massiv ga reference
}, 1000);
}
boshlash();
// setInterval to'xtatilmadi — katta_massiv hech qachon tozalanmaydi
Hayotiy o'xshatma
Mehmonxona jihozi. Mehmon chiqib ketdi — lekin jihozi xonada qoldi. Xona "band" deb hisoblanadi. Keyin yana mehmon chiqib ketdi — yana jihozi qoldi. Mehmonxona to'lib boradi, bo'sh xona qolmaydi. Bu — Memory Leak.
// ✅ — intervallarni to'xtatish
function boshlash() {
const massiv = new Array(100000).fill("x");
const intervalId = setInterval(function() {
console.log(massiv.length);
}, 1000);
return function to'xtatish() {
clearInterval(intervalId); // ← tozalash
};
}
const to'xtat = boshlash();
// ... keyin ...
to'xtat(); // ← interval to'xtatildi, massiv tozalanishi mumkin
3. Unutilgan event listener:
function komponentYarat() {
const kattaMa'lumot = new Array(100000).fill("x");
document.addEventListener("click", function handler() {
console.log(kattaMa'lumot[0]);
});
// handler va kattaMa'lumot — hech qachon tozalanmaydi!
}
// Komponent 100 marta yaratilsa — 100 ta handler, 100 ta kattaMa'lumot
komponentYarat();
komponentYarat();
// ...
// ✅ — listener ni olib tashlash
function komponentYarat() {
const kattaMa'lumot = new Array(100000).fill("x");
function handler() {
console.log(kattaMa'lumot[0]);
}
document.addEventListener("click", handler);
return function tozalash() {
document.removeEventListener("click", handler); // ← olib tashlash
};
}
const tozala = komponentYarat();
// ... keyin komponent o'chirilganda ...
tozala();
4. Map / Set da ob'ektlarni saqlab qolish:
Oldingi darsda ko'rgan holat — Map dagi reference ob'ektni "ushlab turadi".
const kesh = new Map();
function ma'lumotOl(id) {
const ob = { id, ma'lumot: new Array(10000).fill("x") };
kesh.set(id, ob); // ← kesh reference ushlab turadi
return ob;
}
// Har chaqiruvda yangi ob'ekt keshga qo'shiladi — hech biri ketmaydi
for (let i = 0; i < 10000; i++) {
ma'lumotOl(i);
}
// kesh 10,000 katta ob'ektni ushlab turadi
// ✅ — kesh hajmini cheklash yoki WeakMap ishlatish
Closure va Memory Leak
Closure — tashqi o'zgaruvchiga reference ushlab turadi. Ba'zan bu kerakmas ma'lumotni saqlab qolishi mumkin:
function kattaFunksiya() {
const kattaMassiv = new Array(1000000).fill("x"); // 1 million element
return function kichik() {
return "men kichikman";
// kattaMassiv ishlatilmaydi — lekin closure ushlab turadi!
};
}
const fn = kattaFunksiya();
// fn — kichik funksiya, lekin kattaMassiv xotirada
// ✅ — kerak bo'lmagan ma'lumotni null qilish
function kattaFunksiya() {
let kattaMassiv = new Array(1000000).fill("x");
const natija = kattaMassiv.length; // faqat natija kerak
kattaMassiv = null; // ← endi reference yo'q, tozalanishi mumkin
return function() {
return natija; // natija — kichik son, katta massiv emas
};
}
Memory Leak ni aniqlash
Chrome DevTools Memory panel — xotirani kuzatish:
- DevTools → Memory
- "Take heap snapshot" — hozirgi xotira surati
- Bir muddat kutish (ilova ishlaydi)
- Yana "Take heap snapshot"
- Ikki suratsni solishtirish — qaysi ob'ektlar ko'paygan?
Yoki Performance panel → "Record" — vaqt o'tishi bilan xotira grafigi.
Tez-tez uchraydigan xatolar
let/const o'rniga global o'zgaruvchi:
// ❌ — global yaratildi (strict modeda xato)
function f() { natija = []; }
// ✅
function f() { const natija = []; }
Component o'chirilganda tozamaslik:
React, Vue kabi frameworklarda component o'chirilganda — useEffect cleanup, beforeUnmount hook larda intervallar, listener lar to'xtatilishi shart.
Xulosa
Garbage Collection — JavaScript avtomatik xotira tozalash. Ob'ektga yetib borish mumkin bo'lmasa — tozalanadi.
Memory Leak — reference saqlanib qoladi, ob'ekt kerak emas — lekin tozalanmaydi.
Asosiy sabablar:
- Kutilmagan global o'zgaruvchilar
- Tozalanmagan
setInterval - Olib tashlanmagan event listener lar
- Map/Set da keraksiz ob'ektlar (WeakMap ishlatish)
Ilova sekin bo'lib borsa — DevTools Memory panel da memory leak qidiring.
Keyingi dars
66-dars: Funksional dasturlash nima va nima uchun kerak