PDA

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



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

_H2_
28-07-2015, 09:07
سلام
WeakRefrences یکی از ساختارهای ویژه CLR است و کاری که انجام میدهد در موقع لزوم میتواند بسیار جالب و کارآمد باشد...
وقتی شما کلاسی را نمونه سازی میکنید و شی تولیدی را متغییر به متغییر دست به دست میکنید، این یک ارجاع قوی به ماهیت شی در RAM است.

تاوقتی که حتی یک ارجاع قوی به ماهیت یک شی در حافظه دات نت وجود داشته باشد، آن حافظه و شی توسط "جمع آوری کننده حافظه هرز" پاک سازی نمیشود و آن شی در RAM خواهد ماند...

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
در دستورات فوق همواره یک ارجاع قوی به ماهیت شی ای که در خط اول ایجاد شد داشتیم ولی در خط آخر دیگر متغییری که به آن شی اشاره کند نداریم و به garbage اجازه دادیم دخل شی مان را بیاورد!
ولی garbage این را سریع تشخیص نمیدهد و سریع انجام نمیدهد، آن نقطه حافظه شاید تا مدت ها دست نخورده بماند.
گرچه مادیگر آخرین آدرس آن را هم گم کرده ایم و راهی به آن نداریم ولی آن شی میتواند همچنان RAM را اشغال کرده باشد.

حالا ارجاع ضعیف چیست؟
در ارجاع ضعیف، آدرس شی را همچنان داریم ولی جلوی garbage را هم نمیگیریم و اجازه میدهیم اگر خواست یا نیاز شد آن شی را پاک کند.
در مثال قبل بدیهی است تا وقتی من خودم z را null نکنم خودش null نمیشود ! مانند آن است که int i = 123 و تا وقتی i را خودم دست نزم، خوب همان 123 میماند !
ولی در ارجاع ضعیف هرلحظه امکان دارد شی پاک سازی شود و موجودیت آن null شود.

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


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

این امکان میتواند با حجم اطلاعات زیاد در مدیریت حافظه کمک کند...
اگر دچار کمبود حافظه شوید شی پاک میشود وگرنه شاید شانس بیاورید و شی تان سالم بماند ، درواقع در این شرایط بطور معمول باید راه دیگری برای تولید مجدد (new) مشابه مقادیر همان شی داشته باشید.

بعنوان نمونه عملی به شخصه فقط از این امکان یکجا استفاده کردم...
یک پروژه دیتابیس شخصی دارم که خیلی رویش زمان گذاشتم... حتی آرم و اسم و.. هم برایش حاضر کردم...
هسته این دیتابیس برای سطر های جداول از WeakReference استفاده میکند...

توضیحش کاملش خارج از حوصله است ولی در کل بطرز خاصی مجموعه ای از WeakReference را نگاه می دارد...
وقتی به سطری نیاز باشد اول تلاش میکند با WeakReference اطلاعات فیلدهای سطر را مجدد استفاده کند واگر NULL بود آنگاه سراغ read هارد و دی-سریالی اطلاعات میرود...

اینطوری تا وقتی garbage سرکشی نکند و کمبود حافظه هم نباشد از یک سطر خوانده شده از هارد، بارها استفاده میشود و سطری که مدام استفاده شود بیشترین شانس زنده ماندن را خواهد داشت...

با کمک WeakReference هم نیاز نیست چشم بسته همیشه اطلاعات از هارد خوانده شود و برنامه کند شود و هم کل دیتابیس در RAM نمی ماند و مشکل کمبود RAM رخ نخواهد داد

تا وقتی چیزی نیمه جان در حافظه مانده استفاده میشود وگرنه از هارد مجدد تولید میشود...

و...


دقیقاً امکاناتی مشابه این از جمله مواردی است که سطح توقع انسان را از یک محیط و زبان بالا میبرد و توان پذیرش و کارکردن با زبان دیگر با امکانات محدودتر را خیلی سخت میکند، کسی که بنز سوار شده دیگر سوار شدن پراید برایش مشکل خواهد بود !

در ضمن، ساختار GCHandle هم عمل مشابه ای انجام میدهد که در واقع خود از WeakReference هم استفاده میکند.
ساختار TypedReference هم یکی از ساختارهای اصلی بسیار خاص CLR با پارتی بازی های خاص (!) است که در هسته CLR استفاده میشود و نوع دیگر از ارجاع قوی است (کاری که متغییرهای عادی انجام میدهند) ولی یافتن کاربرد برای آن در برنامه نویسی عادی بسیار سخت است.

موفق باشید.