Speed Racer (21-12-17)
سلام
چرا در کد زیر :
کد:int b = 300000; Button[] a = new Button[b]; for (int i = 0; i < a.Length; i++) { a[i] = new Button(); a[i] = null; } a = null; GC.Collect();
GC میتونه حافظه را آزاد کنه ولی در کد زیر که اعضای آرایه را در حلقه ی جداگانه ی دیگه ای null میکنم ، نمیتونه حافظه را آزاد کنه؟ :
کد:int b = 300000; Button[] a = new Button[b]; for (int i = 0; i < a.Length; i++) { a[i] = new Button(); } for (int i = 0; i < a.Length; i++) { a[i] = null; } a = null; GC.Collect();
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (21-12-17)
سلام سجاد جان،
ببخشید با تاخیر دارم جواب میدم.
ما میدونم که 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
'چو ایران نباشد، تن من مباد
Dim Armin As Iranian
If Iran.Enabled = False Then Armin.Enabled = False
SajjadKhati (03-01-18), Speed Racer (03-01-18)
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط ravegoat برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
سلام
ممنون استاد آرمین
یعنی باید متد GC.WaitForPendingFinalizers() ، بعد از GC.Collect() فراخونی بشه؟
اگه آره ، کد را بصورت زیر تغییر دادم ولی کار نکرد :
کد:int b = 300000; Button[] a = new Button[b]; for (int i = 0; i < a.Length; i++) { a[i] = new Button(); } for (int i = 0; i < a.Length; i++) { a[i] = null; } a = null; GC.Collect(); GC.WaitForPendingFinalizers();
قبل اش هم گذاشتم ولی بازم کار نکرد
اگه نه ، کد بالا باید چجوری تغییر کنه تا کار کنه؟
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (03-01-18)
نه اون دو خط آخر این طوری میشه:
کد:GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
'چو ایران نباشد، تن من مباد
Dim Armin As Iranian
If Iran.Enabled = False Then Armin.Enabled = False
SajjadKhati (03-01-18), Speed Racer (03-01-18)
آها ممنون استاد آرمین برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
پس اگه اشتباه نکنم ، متد GC.Collect() که اولین بار صدا زده میشه ، چون منتظر جمع آوری و کارهای مربوط به GC نمیمونه (حالا شاید اون عملیات در یک نخ دیگه اجرا میشه) ، پس نمیتونه اطلاعات را پردازش کنه و کارشو تموم کنه ولی متد GC.WaitForPendingFinalizers() ، باعث توقف اون نخی که اطلاعات را جمع آوری میکنه میشه تا عملیات مربوط به صف ، در GC تمام بشه و بعد که دوباره GC.Collect() را فراخونی میکنیم ، چون اطلاعات مطمئنا جمع آوری شده ، کارشو تموم میکنه و درست انجام میده
میدونم تحلیل ام غلط داره چون از عملکرد GC و توابع هاش چندان اطلاعاتی ندارم
ولی حدودا درست هه؟
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (03-01-18)
سجاد جان بنده همون جملات خودت رو باز نویسی می کنم:
منبعمتد GC.Collect() که اولین بار صدا زده میشه ، چون منتظر جمع آوری و کارهای مربوط به GC نمیمونه (اون عملیات چون Async هستش قطعا در یک نخ دیگه اجرا میشه). متد GC.WaitForPendingFinalizers() ، باعث توقف نخ جاری میشه (نخی که این دستور را صدا زده که مطابق مثال همون Main Thread برنامه هستش) تا عملیات مربوط به صف ، در GC تمام بشه و بعد که دوباره GC.Collect() را فراخونی میکنیم ، چون اطلاعات مطمئنا جمع آوری شده ، کارشو تموم میکنه و درست انجام میده.
'چو ایران نباشد، تن من مباد
Dim Armin As Iranian
If Iran.Enabled = False Then Armin.Enabled = False
SajjadKhati (03-01-18), Speed Racer (03-01-18)
1 کاربر در حال مشاهده این موضوع. (0 عضو و 1 میهمان)
Bookmarks