.NET একটি গার্বেজ কালেকটর (GC) এর মাধ্যমে মেমোরি স্বয়ংক্রিয়ভাবে পরিচালনা করে — এটি ম্যানেজড হিপে অবজেক্ট বরাদ্দ করে এবং যেগুলি আর পৌঁছানো যায় না সেগুলি পুনরুদ্ধার করে, তাই আপনাকে ম্যানুয়ালি মেমোরি মুক্ত করতে হয় না। GC বোঝা (জেনারেশনাল, স্ট্যাক/হিপ বিভাজন, এবং IDisposable) পারফরম্যান্স এবং সঠিকতার জন্য গুরুত্বপূর্ণ।
স্ট্যাক বনাম হিপ
Stack → value types (locals), method frames; fast, automatically freed when scope ends.
Heap → reference type objects (class instances); managed by the GC.
A reference variable lives on the stack but points to its object on the heap.
জেনারেশনাল গার্বেজ কালেকটর
The GC divides the heap into GENERATIONS (based on the "most objects die young" idea):
Gen 0 → newest objects; collected FREQUENTLY (fast, cheap)
Gen 1 → survived one collection
Gen 2 → long-lived objects; collected RARELY (expensive)
(+ Large Object Heap for big objects)
→ Collecting young generations often + old ones rarely makes the GC efficient.
GC রিচেবল অবজেক্টগুলি চিহ্নিত করে (রুট থেকে: স্ট্যাক, স্ট্যাটিক ফিল্ড) এবং বাকিগুলি পুনরুদ্ধার করে। এটি জেনারেশনাল — বেশিরভাগ অবজেক্ট তরুণ অবস্থায় মরে যায়, তাই Gen 0 প্রায়ই এবং সাশ্রয়ীভাবে সংগ্রহ করা হয়, যখন Gen 2-এর দীর্ঘস্থায়ী অবজেক্টগুলি খুব কমই সংগ্রহ করা হয়।
IDisposable এবং using — আনম্যানেজড রিসোর্সের জন্য
// the GC handles MANAGED memory, but NOT unmanaged resources (files, connections, handles)
// → implement IDisposable and use `using` for deterministic cleanup
using (var file = new StreamReader("data.txt"))
{
// use file
} // file.Dispose() called automatically — releases the file handle NOW
GC ম্যানেজড মেমোরি মুক্ত করে, কিন্তু আনম্যানেজড রিসোর্স (ফাইল হ্যান্ডেল, DB সংযোগ, সকেট) IDisposable/Dispose() এর মাধ্যমে সুস্পষ্ট পরিষ্কারের প্রয়োজন — using স্টেটমেন্ট এটি নিশ্চিত করে নির্ধারিতভাবে (আপনি GC এর জন্য অপেক্ষা করেন না)।
মেমোরি লিকস এখনও ঘটে
The GC frees only UNREACHABLE objects. "Leaks" come from lingering references:
✗ static collections/caches that only grow
✗ un-unsubscribed event handlers (the publisher keeps subscribers alive!)
✗ long-lived objects holding references to short-lived ones
কেন এটি গুরুত্বপূর্ণ
.NET মেমোরি ম্যানেজমেন্ট এবং গার্বেজ কালেকশন বোঝা পারফরম্যান্ট, সঠিক C# লেখার জন্য মূল্যবান সিনিয়র-স্তরের জ্ঞান — যদিও GC আপনাকে ম্যানুয়াল মেমোরি ম্যানেজমেন্ট থেকে মুক্ত করে (একটি প্রধান উৎপাদনশীলতা এবং নিরাপত্তার সুবিধা, ম্যানুয়াল free এবং ড্যাঙ্গলিং পয়েন্টার দূর করে), এটি কীভাবে কাজ করে তা বোঝা পারফরম্যান্স-সংবেদনশীল অ্যাপ্লিকেশনের জন্য এবং সূক্ষ্ম বাগ এড়ানোর জন্য গুরুত্বপূর্ণ।
জেনারেশনাল GC বোঝা (Gen 0 ঘন ঘন এবং সাশ্রয়ীভাবে সংগ্রহ করা হয়, Gen 2 কদাচিৎ কিন্তু ব্যয়বহুলভাবে, সেই পর্যবেক্ষণের উপর ভিত্তি করে যে বেশিরভাগ অবজেক্ট তরুণ অবস্থায় মরে যায়) আপনাকে বরাদ্দ প্যাটার্ন এবং GC চাপ সম্পর্কে চিন্তা করতে সাহায্য করে (বরাদ্দ হ্রাস করা, বিশেষত স্বল্পস্থায়ী অবজেক্টগুলির, GC ওভারহেড কমায়)।
স্ট্যাক বনাম হিপ পার্থক্য (স্ট্যাকে মূল্য ধরন, হিপে রেফারেন্স অবজেক্ট) মূল্য/রেফারেন্স ধরনের মডেলের সাথে সংযোগ করে।
গুরুত্বপূর্ণভাবে, IDisposable/Dispose() এবং using স্টেটমেন্ট বোঝা অপরিহার্য এবং ব্যবহারিক: GC মেমোরি পরিচালনা করে কিন্তু আনম্যানেজড রিসোর্স (ফাইল হ্যান্ডেল, ডেটাবেস সংযোগ, সকেট) নয়, যেগুলির using এর মাধ্যমে নির্ধারিত পরিষ্কারের প্রয়োজন — এই বিষয়গুলি নিষ্পত্তি না করা রিসোর্স লিক সৃষ্টি করে (একটি সাধারণ বাস্তব বাগ)।
সমানভাবে গুরুত্বপূর্ণ হল স্বীকার করা যে মেমোরি লিকস এখনও ঘটে GC সত্ত্বেও, লিঙ্গিয়ারিং রেফারেন্স থেকে (ক্রমবর্ধমান স্ট্যাটিক ক্যাশ, আনসাবস্ক্রাইব করা ইভেন্ট হ্যান্ডলার যা সাবস্ক্রাইবারদের জীবিত রাখে — একটি ক্লাসিক C# লিক)।
GC-এর জেনারেশনাল মডেল, রিসোর্স-ডিসপোজাল প্যাটার্ন (IDisposable/using), এবং লিকসের কারণ বোঝা পারফরম্যান্ট, লিক-মুক্ত C# লেখার জন্য গুরুত্বপূর্ণ, বিশেষত দীর্ঘস্থায়ী অ্যাপ্লিকেশনে — যা এটিকে মূল্যবান জ্ঞান করে তোলে যা দক্ষ, সঠিক .NET অ্যাপ্লিকেশন তৈরি করতে পারেন এমন ডেভেলপারদের আলাদা করে এবং একটি সাধারণ সিনিয়র-স্তরের ইন্টারভিউ বিষয়।
