Memory Management & Garbage Collection
"Under the Hood of V8 Engine"
আমরা কোড লিখি, ভেরিয়েবল বানাই, অবজেক্ট তৈরি করি। কিন্তু আমরা কি কখনো ভাবি এই ডাটাগুলো কম্পিউটারের র্যামের (RAM) ঠিক কোথায় জমা হয়? কখন মুছে যায়?
জাভাস্ক্রিপ্ট একটি High-Level Language, অর্থাৎ মেমোরি ম্যানেজমেন্ট সে অটোমেটিক করে (C/C++ এর মতো ম্যানুয়ালি malloc বা free করতে হয় না)। কিন্তু অটোমেটিক বলে আমরা যদি অসতর্ক হই, তবেই তৈরি হয় Memory Leak—যা অ্যাপ স্লো হওয়ার প্রধান কারণ।
চলো ইঞ্জিনের ভেতরে ঢুকি।
⭐ ১. মেমোরি আর্কিটেকচার: Stack vs Heap 🏠
জাভাস্ক্রিপ্ট ইঞ্জিন (V8) মেমোরিকে প্রধানত দুই ভাগে ভাগ করে:
A) The Stack 📚
এটি খুব গোছানো, ফাস্ট এবং সাইজে ছোট।
- কী থাকে: Primitive Values (Number, String, Boolean, null, undefined) এবং ফাংশন কলের রেফারেন্স
- স্ট্রাকচার: LIFO (Last In, First Out)
- এক্সেস: সরাসরি এবং সুপার ফাস্ট
B) The Heap 📦
এটি বিশাল একটি অগোছালো স্টোরেজ বা গুদামঘর।
- কী থাকে: Object, Array, Function (Reference Types)
- স্ট্রাকচার: কোনো অর্ডার নেই, এলোমেলোভাবে ছড়িয়ে থাকে
- এক্সেস: রেফারেন্স বা পয়েন্টার দিয়ে খুঁজে বের করতে হয় (একটু স্লো)
💻 Code Visualization
let age = 30; // Stack-এ ভ্যালু: 30
let name = "Rahim"; // Stack-এ ভ্যালু: "Rahim"
let user = { // Stack-এ থাকে: মেমোরি অ্যাড্রেস (যেমন: 0x001)
id: 1, // Heap-এ থাকে: আসল অবজেক্ট ডাটা { id: 1, role: 'admin' }
role: "admin"
};
// Stack: age, name, user (address)
// Heap: { id: 1, role: "admin" }
⭐ ২. Garbage Collection (GC): অটোমেটিক ক্লিনার 🧹
জাভাস্ক্রিপ্টে একটি ব্যাকগ্রাউন্ড প্রসেস সবসময় চলে, যার নাম Garbage Collector। এর কাজ হলো অব্যবহৃত মেমোরি খুঁজে বের করা এবং ডিলিট করা।
Algorithm: Mark-and-Sweep (The Golden Rule) ✨
মডার্ন ব্রাউজারগুলো এই অ্যালগরিদম ব্যবহার করে। লজিক: "এই অবজেক্টটি কি Reachable (পৌঁছানো সম্ভব)?"
- Roots: গ্লোবাল অবজেক্ট (window) বা কল স্ট্যাকের ভেরিয়েবলগুলোকে রুট ধরা হয়
- Mark: GC রুট থেকে শুরু করে কানেকশন ট্রাভেল করে এবং "Mark" (জীবিত) করে
- Sweep: যাদের মার্ক করা হয়নি, তাদের মেমোরি থেকে "Sweep" বা মুছে ফেলা হয়
let family = { father: { name: "John" } };
// "John" এখন Reachable (family -> father -> John)
family = null;
// কানেকশন কেটে দিলাম। "John" এখন Unreachable.
// GC এসে মেমোরি ক্লিন করে দেবে.
⭐ ৩. Memory Leaks: মেমোরির নীরব ঘাতক ⚠️
অটোমেটিক GC থাকার পরেও মেমোরি লিক হয়। কেন? কারণ আমরা অজান্তেই কিছু অবজেক্টের রেফারেন্স ধরে রাখি, ফলে GC মনে করে ওটা দরকারি এবং ক্লিন করে না।
❌ ১. Global Variables (অজান্তেই গ্লোবাল)
function heavy() {
data = "Huge String..."; // 'var/let/const' দেইনি! হয়ে গেল window.data
}
// এটি window.data হয়ে আজীবন মেমোরিতে থেকে যাবে।
Fix: 'use strict' মোড ব্যবহার করো বা সবসময় let/const দাও।
❌ ২. Forgotten Timers (টাইমার লিক)
const bigData = getData();
const timerId = setInterval(() => {
console.log(bigData); // bigData কে ধরে রেখেছে
}, 1000);
// যদি clearInterval(timerId) না করো, bigData কখনোই মুছবে না।
❌ ৩. Uncensored Event Listeners (DOM লিক)
const btn = document.getElementById("btn");
function handleClick() { ... }
btn.addEventListener("click", handleClick);
// বাটন রিমুভ হওয়ার সময় লিসেনার রিমুভ করতে হবে
❌ ৪. Closures (Scope Trap)
function outer() {
const hugeArray = new Array(1000000);
return function inner() {
console.log("Hello");
};
}
// inner ফাংশনটি বেঁচে থাকলে hugeArray-ও বেঁচে থাকবে
❌ ৫. Detached DOM Nodes (ভুতুড়ে এলিমেন্ট)
let btn = document.getElementById("submit");
document.body.removeChild(btn);
// কিন্তু 'btn' ভেরিয়েবল এখনো মেমোরিতে আছে! Fix: btn = null;
⭐ ৪. V8 Engine Deep Dive: Generations (Senior Topic) 🚀
V8 ইঞ্জিন হিপ মেমোরিকে দুই ভাগে ভাগ করে অপটিমাইজেশন করে:
Young Generation (New Space)
নতুন তৈরি হওয়া অবজেক্ট এখানে আসে। এখানে Scavenge নামক খুব ফাস্ট GC চলে।
Old Generation (Old Space)
যেসব অবজেক্ট ২টা সাইকেল পার করেছে, তারা এখানে প্রমোশন পায়। এখানে Mark-Sweep-Compact নামক ভারী GC চলে।
Senior Insight: আমরা চেষ্টা করব অবজেক্টগুলোকে "ক্ষণস্থায়ী" করতে যাতে তারা Young Generation-এই মারা যায়। Old Generation-এ গেলে GC রান হতে সময় বেশি লাগে এবং অ্যাপ ল্যাগ (Lag) করতে পারে।
⭐ ৫. Node.js Memory Limits (Backend Special) 🟢
ব্রাউজারের মতো নোড আনলিমিটেড মেমোরি পায় না।
- Default: প্রায় 1.7GB (64-bit সিস্টেমে)
- সমস্যা: এর বেশি হলে অ্যাপ ক্র্যাশ করবে "Heap out of memory" এরর দিয়ে
সমাধান: মেমোরি লিমিট বাড়ানো
node --max-old-space-size=4096 server.js # 4GB করলাম
⭐ ৬. Debugging Tools (Chrome DevTools) 🛠️
মেমোরি লিক ধরবে কিভাবে? Chrome DevTools এর Memory ট্যাব ব্যবহার করে।
- Heap Snapshot: মেমোরির ছবি তোলে। দুইটা স্ন্যাপশট নিয়ে তুলনা (Compare) করে দেখবে কোন অবজেক্ট ডিলিট হচ্ছে না
- Allocation Instrumentation: টাইমলাইনের সাথে মেমোরি বাড়া-কমা দেখায়
🧠 ৭. Senior Checklist: Best Practices
- ✓WeakMap/WeakSet: ক্যাশিং বা DOM ট্র্যাকিংয়ের জন্য সবসময় WeakMap ব্যবহার করো
- ✓Clear Intervals: কম্পোনেন্ট আনমাউন্ট হওয়ার সময় clearInterval বা clearTimeout দাও
- ✓Nullify References: বড় কাজ শেষ হলে ভেরিয়েবল null করে দাও
- ✓Avoid Global: গ্লোবাল স্কোপে ভারী ডাটা রাখবে না
- ✓Pagination: একসাথে ১০,০০০ ডাটা না এনে পেজিনেশন ব্যবহার করো
🎤 ৮. Senior Level Interview Questions
Q1: Stack এবং Heap এর মধ্যে প্রধান পার্থক্য কী?
উত্তর: Stack প্রিমিটিভ ডাটা এবং রেফারেন্স রাখে (ফাস্ট), Heap অবজেক্টের আসল ডাটা রাখে (স্লো কিন্তু বড়)।
Q2: Garbage Collector কীভাবে কাজ করে?
উত্তর: Mark-and-Sweep অ্যালগরিদম ব্যবহার করে। Roots থেকে Reachable অবজেক্টগুলো Mark করে, বাকিগুলো Sweep করে মুছে ফেলে।
Q3: মেমোরি লিকের সবচেয়ে কমন কারণ কী?
উত্তর: ভুলে যাওয়া টাইমার (setInterval), আনক্লিনড ইভেন্ট লিসেনার, গ্লোবাল ভেরিয়েবল, এবং DOM রেফারেন্স মুছে না ফেলা।
🚀 অধ্যায় ২০ সারাংশ (Checklist)
- ✓Architecture: Primitives Stack-এ, Objects Heap-এ
- ✓GC Algorithm: Mark-and-Sweep মেথডে Unreachable অবজেক্ট ক্লিন হয়
- ✓Leaks Causes: ইভেন্ট লিসেনার, টাইমার, ক্লোজার, গ্লোবাল ভেরিয়েবল
- ✓Tools: Chrome Memory Tab, Heap Snapshot, Allocation Timeline
- ✓Solutions: WeakMap, Cleanup Mechanism, Nullify References
অভিনন্দন! 🎉 তুমি জাভাস্ক্রিপ্টের মেমোরি ম্যানেজমেন্ট শেষ করেছো। এর মাধ্যমে আমাদের Core JavaScript & Advanced Internals সেকশন শেষ হলো।