Garbage Collection(جمع آوری زباله) در دات نت چیست؟
به طور کلی، Garbage Collection (GC) چیزی نیست جز به دست آوردن مجدد حافظه اختصاص داده شده به اشیایی که در حال حاضر در هیچ بخشی از برنامه ما استفاده نمی شوند.
هنگامی که یک شی در سی شارپ ایجاد می کنیم،یک حافظه برای شی در حافظه heap تخصیص داده می شود. حافظه heap به طور کامل توسط Common Language Runtime (CLR) در چارچوب دات نت مدیریت می شود. تخصیص حافظه و توزیع در heap توسط CLR انجام می شود. همیشه برای هر چیزی محدودیتی وجود دارد، در چنین مواردی حافظه نیز محدود است. ما باید مقداری حافظه را در heap پاک کنیم تا CLR بتواند حافظه را به اشیاء تازه ایجاد شده اختصاص دهد.
Win32 DLL (Dynamic Link Library) در سیستم عامل بسته به نسخه سیستم عامل 32 بیتی یا 64 بیتی وظیفه مراقبت از تخصیص حافظه را دارد. برای سیستم عامل های 32 بیتی، حداکثر رمی که می تواند پشتیبانی کند تا 4 گیگابایت است. تخصیص حافظه مجازی به حداکثر 2 گیگابایت توسط Win32 DLL محدود شده است. حافظه Heap نیز از طریق این حافظه مجازی مدیریت می شود.
Common Language Runtime چیست؟
چارچوب دات نت برای اجرای کد یک محیط run-time به نام Common Language Runtime (CLR) را فراهم می کند و خدماتی را ارائه می دهد که فرآیند توسعه را آسان تر می کند.
تصویر زیر رابطه CLR و کتابخانه کلاس را با برنامه های ما و سیستم کلی نشان می دهد.
در CLR، Garbage Collector به عنوان یک مدیر حافظه خودکار عمل می کند.
کدهای مدیریت شده و مدیریت نشده در سی شارپ چیست؟
تمام اشیایی که تحت حیطه CLR ایجاد و مدیریت می شوند، کدهای مدیریت شده(Managed Code) نامیده می شوند. هنگامی که یک شی خارج از CLR مانند File Stream، کانکشن های پایگاه داده، سوکت های شبکه و اشیاء COM ایجاد و مدیریت می شود را کدهای مدیریت نشده(UnManaged Code) می نامند. حافظه تخصیص یافته به اشیاء مدیریت نشده را می توان با استفاده از متد Dispose که از اینترفیس IDisposable استفاده می کند را بازیابی کرد.
Garbage Collection چه زمانی اتفاق می افتد؟
Garbage Collection در صورتی اتفاق می افتد که حداقل یکی از شرایط زیر برآورده شود. این شرایط به شرح زیر است:
- اگر سیستم حافظه فیزیکی پایینی دارد، Garbage Collection ضروری است.
- اگر حافظه تخصیص داده شده به اشیاء مختلف در حافظه heap از یک آستانه از پیش تعیین شده فراتر رود، Garbage Collection اتفاق می افتد.
- اگر متد GC.Collect فراخوانی شود، Garbage Collection اتفاق می افتد. با این حال، این روش تنها در شرایط غیرعادی فراخوانی می شود، زیرا به طور معمول Garbage Collection به طور خودکار انجام می شود.
فازهای Garbage Collection
در Garbage Collection عمدتاً 3 فاز وجود دارد. جزئیات در مورد این موارد به شرح زیر است:
- فاز علامت گذاری: لیستی از تمام اشیاء زنده در طول مرحله علامت گذاری ایجاد می شود. این کار با دنبال کردن رفرنس ها از تمام اشیاء روت انجام می شود. تمام اشیایی که در لیست اشیاء زنده نیستند به طور بالقوه از حافظه heap حذف می شوند.
- فاز جابجایی : رفرنس های همه اشیایی که در لیست تمام اشیاء زنده بودند در مرحله جابجایی به روز می شوند تا به مکان جدیدی که در مرحله فشرده سازی اشیاء به آنجا منتقل می شوند اشاره کنند.
- فاز فشرده سازی: heap در مرحله فشرده سازی فشرده می شود، زیرا فضای اشغال شده توسط اشیا مرده آزاد می شود و اشیا زنده باقی مانده جابجا می شوند. تمام اشیاء زنده که پس از Garbage Collection یا جمع آوری زباله باقی می مانند به ترتیب اصلی خود به سمت انتهای قدیمی حافظه heap منتقل می شوند.
Generation های حافظه Heap در Garbage Collection(جمع آوری زباله)
در سی شارپ ما 3 Generation داریم:
- Generation 0 مکانی است که تمام اشیاء جدید ایجاد شده در آن قرار می گیرند که به عنوان اشیاء کوتاه مدت نیز در نظر گرفته می شود.
- Generation 1 مکانی است مانند بافر بین اجسام کوتاه و طولانی.
- Generation 2 اجسام با عمر طولانی هستند. اشیایی که برای اعضای Static ایجاد می شوند ومتغیرهای سراسری مستقیماً در نسل 2 قرار می گیرند و در نظر می گیرد که این اشیاء طول عمر بیشتری نسبت به بقیه دارند.
وقتی مجموعهای در Generation 2 وجود دارد، آن را garbage collection کامل مینامیم زیرا از تمام اشیاء موجود در حافظه مدیریت شده عبور میکند. CLR با استفاده از GC از این Generation ها مراقبت می کند.
وقتی اندازه شی بزرگتر از 85000 بایت باشد، مستقیماً در Generation 2 قرار می گیرد.
Garbage Collection اغلب در Generation 0 اتفاق میافتد، جایی که اکثراً اشیاء زنده کوتاه داریم. وقتی GC متوجه شد که اشیاء هنوز در برنامه زندگی می کنند تمام آن اشیاء را به Generation 1 منتقل می کند که به عنوان Survivors نامیده می شود. وقتی GC در Generation 1 اتفاق می افتد، همه اشیاء زنده به Generation 2 منتقل می شوند. همه اشیاء Generation 2 اشیایی هستند که عمر طولانی دارند و عمدتاً برای کل طول عمر برنامه در آنجا باقی می مانند. در غیر این صورت، آن اشیا نیز توسط GC هنگامی که در Generation 2 اجرا می شود، بازیابی می شوند.
چگونه GC از اشیاء زنده مطلع می شود
قبل از اینکه GC شروع به اجرا کند، تمام تردهای مدیریت شده به حالت تعلیق در می آیند به جز یک ترد که GC را راه اندازی کرده است. هنگامی که Garbage Collections شروع به اسکن برای اشیاء در Generation 0 می کند یک درخت برای همه اشیای زنده ایجاد می کند. اگر هر یک از اشیاء در درخت شرکت نکند، به این معنی است که شی دیگر در هیچ بخشی از برنامه استفاده نمی شود و به عنوان Garbage در نظر گرفته می شود و از بین رفته و حافظه دوباره برمی گردد.
در پایان فرآیند GC، مسئولیت Garbage Collector این است که آدرس حافظه را از اشیاء حذف شده به اشیای زنده تخصیص دهد. با انجام این کار حافظه شی فشرده می شود.
وقتی حافظه مجازی کمتری داریم GC به طور خودکار فعال میشود و توصیه نمیشود که GC را به صورت برنامه ریزی فراخوانی کنیم و بهتر است که بگذاریم خودش اتفاق بیفتد. اجرای GC بر عملکرد برنامه شما تأثیر نمی گذارد.
متد ها در کلاس GC در سی شارپ
کلاس GC زباله جمع کن سیستم یا garbage collector را کنترل می کند. برخی از متدهای کلاس GC به شرح زیراست:
متد ()GC.GetGeneration: این متد شماره generation شی مورد نظر را برمی گرداند. به یک پارامتر واحد نیاز دارد، یعنی شی هدفی که برای آن شماره generation مورد نیاز است.
using System;
public class Demo {
public static void Main(string[] args)
{
Demo obj = new Demo();
Console.WriteLine("The generation number of object obj is: "+ GC.GetGeneration(obj));
}
}
//Output:
The generation number of object obj is: 0
متد ()GC.GetTotalMemory: این متد تعداد بایت هایی را که در سیستم تخصیص داده شده است را برمی گرداند و به یک پارامتر boolean نیاز دارد که در آن true به این معنی است که متد قبل از بازگشت نتیجه منتظر وقوع جمع آوری زباله می ماند و false به معنای مخالف آن است.
using System;
public class Demo {
public static void Main(string[] args)
{
Console.WriteLine("Total Memory:" + GC.GetTotalMemory(false));
Demo obj = new Demo();
Console.WriteLine("The generation number of object obj is: "+ GC.GetGeneration(obj));
Console.WriteLine("Total Memory:" + GC.GetTotalMemory(false));
}
}
//Output:
Total Memory:4197120
The generation number of object obj is: 0
Total Memory:4204024
توجه: خروجی ممکن است متفاوت باشد زیرا بستگی به سیستم دارد.
متد ()GC.Collect: جمع آوری زباله را می توان با استفاده از متد ()GC.Collect در سیستم اجباری کرد. این روش به یک پارامتر نیاز دارد، یعنی عدد قدیمیترین Generation که برای آن جمعآوری زباله انجام میشود.
using System;
public class Demo {
public static void Main(string[] args)
{
GC.Collect(0);
Console.WriteLine("Garbage Collection in Generation 0 is: "+ GC.CollectionCount(0));
}
}
//Output:
Garbage Collection in Generation 0 is: 1
مزایای Garbage Collection یا جمع آوری زباله چیست؟
- Garbage Collection با استفاده از Generation ها می تواند اشیاء را به طور موثر بر روی حافظه Heap تخصیص دهد.
- نیازی به آزادسازی دستی حافظه نیست زیرا جمع آوری زباله به طور خودکار فضای حافظه را پس از عدم نیاز به آن آزاد میکند.
- جمعآوری زباله، تخصیص حافظه را به طور ایمن مدیریت میکند تا هیچ شیئی به اشتباه از محتویات یک شی دیگر استفاده نکند.
- سازندگان اشیاء تازه ایجاد شده مجبور نیستند تمام فیلدهای داده را مقداردهی اولیه کنند زیرا جمع آوری زباله حافظه اشیایی را که قبلاً منتشر شده اند پاک می کند.
برای ثبت نظر باید در سایت ثبت نام یا ورود نمایید