Garbage Collector چیست
کمی درباره Garbage Collector در NET.
بحث GC از این فایل (https://github.com/dotnet/coreclr/blob/master/src/gc/gc.cpp)داخل پروژه CoreCLR ماکروسافت شروع میشه. Head تیم GC در NET. خانومی به اسم Maoni Stephens (https://devblogs.microsoft.com/dotnet/author/maoni/) هست.
زبان ها به 2 دسته Managed و Unmanaged تقسیم میشن و بعضی ها از جمله #C هم این قابلیت رو دارن که داخلشون با اینکه بطور پیشفرض Managed هستن ، اما Unmanaged هم کد بزنید ( Unsafe ) .
تفاوت Managed و Unmanaged چیه ؟
در #C شما معمولا یک کلاس میسازید ، اون رو new میکنید و ازش استفاده میکنید و درگیر چیز خاصی نمیشید ; اما در پشت صحنه این new کردن باعث allocate شدن یک object داخل memory heap میشه ; به ازای هر new شدن یک کلاس ، شما یک object جدید رو داخل Memory میاید allocate میکنید.
این object ها ، بعد از پایان کار شما از بین برن وگرنه باعث پر شدن Memory و OutOfMemoryException میشه و برنامه شما Crash میکنه.
ساختار Managed در #C به این صورت هست که کد شما تبدیل به یک Intermediate Language تبدیل میشه و وظیفه از بین بردن Object های اضافی که کار برنامه با اونها تموم شده و باید از بین برن ، بر عهده Garbage Collector هست.

Garbage Collector چیست
در زبان های Unmanaged ، وقتی شما یک کلاس میسازید و اون رو new میکنید ، مجبور هستید که بعد از پایان کارتون ، خودتون این object رو “تشخیص” بدید که الان بی استفاده شده ( Garbage ) و از بین ببریدش.
تشخیص اینکه یک Object در حال حاضر Garbage و بی استفاده هست ، کار مشکلی هست و در Managed Code ، این وظیفه بر عهده GC هست.
به Object هایی که شما داخل کدتون Allocate میکنید ، Root Objects گفته میشه. هر Root میتونه وابستگی به کلاس های مختلف دیگه ای داخل خودش داشته باشه ; بعنوان مثال کلاس Person میتونه داخل خودش Property ای از جنس Address داشته باشه که خود Address هم روی Memory یک Allocation ای داره.
تشخیص Garbage بودن Person کار مشکلی هست ، چون GC باید تمام وابستگی های Person رو از جمله متدها ، Property ها ، فیلدها و … رو چک کنه ( مثل Address ) و ببینه که کلاس Person و یا Address داخل این کلاس ، در تمام AppDomain برنامه ، در حال استفاده هست یا خیر. Object هایی که در حال حاضر در برنامه کاربرد دارن و مورد استفاده قرار گرفتن ، Reachable Objects نامیده میشن به این معنی که هنوز قابل دسترسی هستن و خلافش هم Garbage به حساب میان.
موقع انجام Collection در GC ، سه مرحله اتفاق میوفته :
1- Marking Phase
در این مرحله ، همونطور که بالاتر گفتیم ، لیست Object های زنده برنامه پیدا میشه و بعنوان Reachable Objects یک Flag میخورن.
2- Relocating Phase
در این مرحله ، Dependency های کلاس های Reachable ، داخل Memory جاشون عوض میشه. GC موقع Collect شدن ، ممکن هست جای Object هایی که Allocate شدن رو تغییر بده و Memory Address اون هارو تغییر بده.
این مرحله باعث میشه که تغییرات Address ، باعث وجود مشکل نشه چون ممکن هست Address داخل کلاس Person تغییر کنه و اگر این Step اتفاق نیوفته ، باعث بوجود اومدن NullReferenceException میشه بدلیل عوض شدن آدرس Address.
3- Compacting Phase
در این مرحله ، Dead Object ها توسط GC از بین میرن و جای Object های داخل Memory هم تغییر میکنن و عملا یه defragmentation داخل Memory اتفاق میوفته.
در Memory Heap سه بخش ( Generation ) وجود داره و Object ها تو یکی از این 3 بخش قرار میگیرن.
GEN 0 :
تمام Object هایی که در ابتدا Allocate میشن ، داخل GEN 0 میرن. Collection در ابتدا روی این Generation اتفاق میوفته و اکثر Object های موجود در این GEN قابل Collect شدن و از بین رفتن هستن ( معمولا Short-Lived Object ها مثل یک Local Variable از نوع string داخل یک متد )
اگر Object های داخل این Generation ، وابستگی داشته باشن و به هر دلیلی نتونن Collect بشن ، Object های زنده ، به GEN 1 منتقل میشن.
GEN 1 :
هر Object ای که در مرحله قبل نتونستن از بین برن ، به اینجا منتقل میشن. تعداد دفعات انجام Collection روی GEN 0 توسط GC از بقیه Generation ها بیشتر هست و با منتقل شدن Object به Level های بالاتر ، روی اون Generation ها ، تعداد دفعات Collect شدن کمتر و زمان انجام اینکار بیشتر میشه.
GEN 2 – Large Object Heap ( LOH ) :
اگر Object ای در GEN 0 و GEN 1 نتونسته Collect بشه ، به LOH فرستاده میشه. تعداد دفعات انجام Collection روی این Generation بسیار کم هست بدلیل اینکه Object هایی که به اینجا منتقل شدن ، قطعا Object های سنگین و یا دارای Reference های زیاد و یا Static Object ها هستن که طول عمر این Object ها برابر با طول عمر Process برنامه هست. بدلیل سنگین بودن این Object ها و زمان زیادی که برای حذف اینها نیاز هست ، اکثر اوقات Collection روی این Generation اتفاق نمیوفته.