🧠 کالبدشکافی حافظه در C# Stack در برابر Heap
وقتی یه متغیر تعریف میکنید، دقیقاً کجا میره؟ چرا بعضی متغیرها بلافاصله بعد از خروج از متد از بین میرن ولی بعضی دیگه باقی میمونن؟
جواب این سوالها تو دو تا از مهمترین مفاهیم کامپیوتر نهفتهست: Stack (پشته) و Heap (هیپ). درک این دو، شما رو از یه کدنویس ساده به یه توسعهدهنده واقعی تبدیل میکنه.
1️⃣پشته (Stack) :
حافظهی سریع و منظم فکر کنید Stack مثل یه دسته بشقابه که روی هم چیدید. آخرین بشقابی که میذارید، اولین بشقابیه که برمیدارید (LIFO: Last-In, First-Out).
چی توش ذخیره میشه؟ این بخش از حافظه برای ذخیرهی متغیرهای محلی و پارامترهای متدها استفاده میشه. بیشتر Value Type ها اینجا زندگی میکنن.
چطور کار میکنه؟ با هر بار صدا زدن یک متد، حافظه مورد نیاز اون متد بالای پشته قرار میگیره و با تمام شدن متد، اون بخش از حافظه بلافاصله آزاد میشه. این کار فوقالعاده سریعه.
static int Factorial (int x)
{
if (x == 0) return 1;
return x * Factorial (x - 1);
}
هر بار که Factorial خودشو صدا میزنه، یه int x جدید روی پشته ساخته میشه و با برگشتن جواب، اون int از روی پشته برداشته میشه.
2️⃣هیپ (Heap) :
هیپ مثل یه انبار بزرگه. هر وقت یه آبجکت جدید میسازید (new)، CLR یه جای خالی تو این انبار پیدا میکنه، آبجکت رو اونجا میذاره و یه "آدرس" یا "رفرنس" به شما برمیگردونه.
چی توش ذخیره میشه؟ تمام آبجکتها (نمونههای Reference Type) اینجا زندگی میکنن.
چطور کار میکنه؟ این حافظه توسط یه رفتگر هوشمند به اسم Garbage Collector (GC) مدیریت میشه. GC هر چند وقت یکبار میاد و آبجکتهایی که دیگه هیچ رفرنسی بهشون اشاره نمیکنه (آبجکتهای یتیم) رو از حافظه پاک میکنه تا فضا آزاد بشه.
StringBuilder ref1 = new StringBuilder("obj1");
Console.WriteLine(ref1);
// بعد از این خط، دیگه هیچ رفرنسی به آبجکت "obj1" اشاره نمیکنه
// و آماده پاک شدن توسط GC میشه.
StringBuilder ref2 = new StringBuilder("obj2");
StringBuilder ref3 = ref2;
// اینجا با اینکه ref2 دیگه استفاده نمیشه، چون ref3 هنوز به "obj2"
// اشاره میکنه، این آبجکت زنده میمونه!
Console.WriteLine(ref3);نکته: فیلدهای استاتیک هم روی هیپ ذخیره میشن، ولی تا پایان عمر برنامه زنده میمونن.
🤔 پس Value Typeها دقیقاً کجا زندگی میکنند؟
این سوال مهمیه! قانونش اینه: Value Typeها هرجا که تعریف بشن، همونجا زندگی میکنن.
اگه به عنوان یه متغیر محلی تو یه متد تعریف بشن ⟵ روی Stack.
اگه به عنوان یه فیلد داخل یه کلاس (که خودش یه Reference Type هست) تعریف بشن ⟵ همراه با اون آبجکت روی Heap!
حرف حساب و درک عمیقتر
درک تفاوت Stack و Heap فقط یه بحث تئوری نیست؛ روی پرفورمنس، مدیریت حافظه و حتی نحوه طراحی کلاسهای شما تأثیر مستقیم داره.
این توضیح چقدر به درک بهتر شما از رفتار Value Type و Reference Type کمک کرد؟ آیا نکتهای در مورد Stack و Heap بود که براتون تازگی داشته باشه؟
نظراتتون رو کامنت کنید! 👇
[پاتوق گیک های #C]
🔖 هشتگها :
#CSharp
#MemoryManagement
#DotNet #Stack #Heap