سلام سجاد جان،
ببخشید با تاخیر دارم جواب میدم.
ما میدونم که GC به طور خودکار اجرا میشه. در کد اول حین اجرای حلقه، ما یک شی جدید تولید می کنیم و بی درنگ اون رو خالی می کنیم. وقتی حلقه پیشروی می کنه، GC با اشیایی رو به رو میشه که هیچ ارجاعی بهشون وجود نداره و در نتیجه اون ها رو Collect می کنه. در نتیجه در ابتدا حافظه ی مصرفی افزایش پیدا می کنه ولی پس از مدتی ثابت می مونه (زمانی که نرخ تولید با نرخ جمع آوری برابر بشه). در نهایت هم که دستور GC.Collect رو اجرا کنیم، GC با اشیایی کمی رو به رو خواهد بود که هنوز جمع آوری نشدن. لذا به سرعت حافظه پاک سازی میشه.
در کد دوم هم GC در حین پیشروی حلقه ها به اجرا در میاد. با این تفاوت که در حلقه ی اول تنها اشیا تولید میشن ولی ارجاعی نسبت به اون ها وجود داره (در حلقه ی دوم ما نسبت به این اشیا ارجاع داریم). در نتیجه GC نمی تونه چیزی رو Collect کنه و حافظه ی مصرفی افزایش پیدا می کنه. حلقه ی دوم نسبت به حلقه ی اول بسیار سریع تر اتفاق می افته. در این حالت GC تا به خودش بیاد که کدوم اشیا خالی شدن، حلقه ی دوم تموم شده. حالا GC می مونه و کلی اشیا که باید جمع آوری کنه. GC برای جمع هر شی، Finalizer اون رو صدا می زنه. متد Finalizer برای کلاس Button به نسبت زمان بره. تو این حالت GC این اشیا رو داخل یک صف قرار میده تا اجرای Finalizer هاشون به اتمام برسه. با دستور GC.WaitForPendingFinalizers ما صبر می کنیم تا این صف خالی باشه. در نهایت اگر مجددا دستور GC.Collect رو صدا بزنیم می بینیم که حافظه مقداری مشابه کد اول خواهد داشت.
برای اطلاعات بیش تر:
https://msdn.microsoft.com/en-us/lib...v=vs.110).aspx
https://blog.stephencleary.com/2010/...o-null-to.html
https://blogs.msdn.microsoft.com/old...09-00/?p=13203
C# Tips & Tricks: Weak References - When and How to Use Them
https://stackoverflow.com/questions/...s-finer-points






پاسخ با نقل قول
Bookmarks