PDA

مشاهده نسخه کامل : ارجاع های ضعیف در سی شارپ



iranch
23-07-15, 22:38
درود
کسی میتونه یک توضیح خوب و جامع با مثال در مورد WeakRefrences ها بزنه؟ منبع فارسی هم ندیدم. مطمئنا دوستان دیگر هم از گوگل میتونن این مطلب رو پیدا کنن و بهره ببرن
شخضا چندساعت وقت گذاشتم اما به جایی نرسیدم و مثال ها معلوم نشد چی به چی هست :1. (29):

ravegoat
03-08-15, 11:57
با سلام!

به طور پیش فرض هر ارجاعی که ما در سی شارپ تعریف می کنیم از نوع قوی خواهد بود (Strong References). مثلا وقتی یک متغیر از نوع Image تعریف می کنیم، این تعریف از نوع قوی هستش. متغیری که این طوری تعریف بشه به طور دائم در حافظه مقیم خواهد بود حتی اگر برنامه ای که تعریفش کرده باشه دیگه باهاش کار نداشته باشه. فرضا همون Image ای که تعریف شده توسط یک برنامه، شاید یه بار فرخوانی بشه و دیگه بهش نیازی نباشه. در این صورت چون ارجاع به شکل قوی بوده تا زمانی که پروسه ی برنامه در جریان باشه، این تصویر در حافظه خواهد موند در حالی که در عمل واقعا دیگه نیازی نیست اون تصویر در حافظه باشه. در نتیجه اگه در یک برنامه ی بزرگ با متغیر های زیادی سر و کار داشته باشیم و همه ی اون ها به شکل قوی تعریف بشن، به مرور ممکنه حافظه پر بشه.
با این اوصاف مهندسین تصمیم گرفتن برای مدیریت بهتر حافظه متغیر هایی رو تعریف کنن که حتی اگه پروسه ی برنامه در جریان باشه، بتونند این متغیر ها را از حافظه پاک کنند. اون ها اسم این نوع تعریف رو ارجاع ضعیف گذاشتن. در این نوع ارجاع مکانیزمی به اسم Garbage Collector یا GC وجود داره که متغیر های بدون استفاده رو از حافظه پاک می کنه. طبق اون مثال اگه Image به شکل ضعیف تعریف بشه، برنامه هر وقت که کارش با تصویر تموم شد می تونه فرمان GC.Collect رو اجرا کنه و بعد از اون GC تمام متغیر هایی رو که به شکل ارجاع ضعیف باشن از حافظه پاک خواهد کرد و در نهایت حافظه با متغیر های بدون استفاده اشغال نخواهد شد.
برای استفاده از این قابلیت در سی شارپ می تونید به پیوند زیر مراجعه کنید:
Only the registered members can see the link
ایده ی Weak References شاید خیلی برای بحث Caching مفید به نظر بیاد ولی در نظر داشته باشیم که GC مکانیزم صد در صد مطمئنی نیست و از طرفی این نوع ارجاع شاید در برخی حالت ها، سرعت برنامه رو کاهش بده. برای اطلاعات بیش تر مراجعه کنید به:
Understanding weak references in .NET - CodeProject (Only the registered members can see the link)
و در آخر برای درک سایر انواع ارجاع ها، سر زدن به پیوند زیر خالی از لطف نخواهد بود:
Only the registered members can see the link

iranch
11-08-15, 04:48
با سلام!

به طور پیش فرض هر ارجاعی که ما در سی شارپ تعریف می کنیم از نوع قوی خواهد بود (Strong References). مثلا وقتی یک متغیر از نوع Image تعریف می کنیم، این تعریف از نوع قوی هستش. متغیری که این طوری تعریف بشه به طور دائم در حافظه مقیم خواهد بود حتی اگر برنامه ای که تعریفش کرده باشه دیگه باهاش کار نداشته باشه. فرضا همون Image ای که تعریف شده توسط یک برنامه، شاید یه بار فرخوانی بشه و دیگه بهش نیازی نباشه. در این صورت چون ارجاع به شکل قوی بوده تا زمانی که پروسه ی برنامه در جریان باشه، این تصویر در حافظه خواهد موند در حالی که در عمل واقعا دیگه نیازی نیست اون تصویر در حافظه باشه. در نتیجه اگه در یک برنامه ی بزرگ با متغیر های زیادی سر و کار داشته باشیم و همه ی اون ها به شکل قوی تعریف بشن، به مرور ممکنه حافظه پر بشه.
با این اوصاف مهندسین تصمیم گرفتن برای مدیریت بهتر حافظه متغیر هایی رو تعریف کنن که حتی اگه پروسه ی برنامه در جریان باشه، بتونند این متغیر ها را از حافظه پاک کنند. اون ها اسم این نوع تعریف رو ارجاع ضعیف گذاشتن. در این نوع ارجاع مکانیزمی به اسم Garbage Collector یا GC وجود داره که متغیر های بدون استفاده رو از حافظه پاک می کنه. طبق اون مثال اگه Image به شکل ضعیف تعریف بشه، برنامه هر وقت که کارش با تصویر تموم شد می تونه فرمان GC.Collect رو اجرا کنه و بعد از اون GC تمام متغیر هایی رو که به شکل ارجاع ضعیف باشن از حافظه پاک خواهد کرد و در نهایت حافظه با متغیر های بدون استفاده اشغال نخواهد شد.
برای استفاده از این قابلیت در سی شارپ می تونید به پیوند زیر مراجعه کنید:
Only the registered members can see the link
ایده ی Weak References شاید خیلی برای بحث Caching مفید به نظر بیاد ولی در نظر داشته باشیم که GC مکانیزم صد در صد مطمئنی نیست و از طرفی این نوع ارجاع شاید در برخی حالت ها، سرعت برنامه رو کاهش بده. برای اطلاعات بیش تر مراجعه کنید به:
Understanding weak references in .NET - CodeProject (Only the registered members can see the link)
و در آخر برای درک سایر انواع ارجاع ها، سر زدن به پیوند زیر خالی از لطف نخواهد بود:
Only the registered members can see the link

ممنون از پاسخ شما،اما خوب ما بیائیم یک عکس رو ارجاع ضعیف تعریف کنیم و بعد زباله روب رو فراخوانی کنیم تا اون رو از حافظه پاک کنه؟ درسته؟ خوب میائیم از نوع معمولی یا همان قوی تعریف میکنیم و دستی اون رو حذف میکنیم از کل برنامه بعد از استفاده خودمون!
خوب راه حل من اگر بعد به اون نیاز داشته باشیم دیگر عکس رو نداریم
اما راه حل ارجاع های ضعیف اگر به فرض بعد از پاک شدن، ما به اون نیاز پیدا کردیم، اون رو مجدد در حافظه لود خواهد کرد؟ اگر لود میکنه ، شاید یک زمانی هست که ما نمیتونیم تشخیص بدیم و دستور زباله روب رو براش بنویسیم..اون وقت چی؟ باز برای همیشه در حافظه میمونه؟!

ravegoat
11-08-15, 08:03
ممنون از پاسخ شما،اما خوب ما بیائیم یک عکس رو ارجاع ضعیف تعریف کنیم و بعد زباله روب رو فراخوانی کنیم تا اون رو از حافظه پاک کنه؟ درسته؟ خوب میائیم از نوع معمولی یا همان قوی تعریف میکنیم و دستی اون رو حذف میکنیم از کل برنامه بعد از استفاده خودمون!
خوب راه حل من اگر بعد به اون نیاز داشته باشیم دیگر عکس رو نداریم
اما راه حل ارجاع های ضعیف اگر به فرض بعد از پاک شدن، ما به اون نیاز پیدا کردیم، اون رو مجدد در حافظه لود خواهد کرد؟ اگر لود میکنه ، شاید یک زمانی هست که ما نمیتونیم تشخیص بدیم و دستور زباله روب رو براش بنویسیم..اون وقت چی؟ باز برای همیشه در حافظه میمونه؟!
دوست عزیز تو بخش So, are the weak references useless? مقاله ی زیر جواب سوالتون اومده:
Understanding weak references in .NET - CodeProject (Only the registered members can see the link)
اگر متوجه نشدید، بفرمایید تا براتون شرح بدم قضیه چیه:1. (26):