چند وقت پیش یه مشکلی داشتم: یه برنامه c# داشتم که به شدت نشت حافظه (memory leak) داشت. یعنی آبجکتهایی داشتم که حافظهای که مصرف میکردن رو آزاد نمیکردن. قضیه از چه قرار بود؟ این تیکه کد رو ببینید:
۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹ ۱۰ ۱۱ ۱۲ ۱۳ ۱۴ ۱۵ |
public class EventProvider { public event EventHandler AnEvent; } public class EventInvoker { public void ProblematicMethod() { EventProvider p = new EventProvider(); p.AnEvent += new AnEvent(Handler); } public void Handler(Object sender, EventArgs e){} } |
اینجا یه کلاس EventProvider داریم که event ارائه میکنه. تو کلاس EventInvoker هم یه متد ProblematicMethod داریم. این متد یه نمونه از کلاس EventProvider میسازه و خودش رو به event محترم وصل میکنه. اما وقتی متد ProblematicMethod کارش تموم میشه چی میشه؟ از دیدگاه .net نمونه ایجاد شده از کلاس EventProvider هنوز باید تو حافظه بمونه. چونکه اون event هنوز وصله. اینجوری با هر بار فراخوانی ProblematicError یه نمونه جدید از کلاس EventProvider ساخته میشه و تو حافظه مستقر میشه. و این میشه یه منشا رخنه حافظه.
البته شاید نشه اسم این مساله رو دقیقا نشت حافظه گذاشت. اما اگه بهش توجه نشه، خیلی راحت نهایتا با کمبود حافظه مواجه میشیم. راه حلش هم به سادگی اینه که وقتی کارمون با یه کلاس تموم شد، دستی event هاش رو آزاد کنیم. به هر حال باید دقت کرد که مدیریت حافظه توسط فریمورک یه ابزار جادویی نیست که بشه هر کاری باهاش کرد.
حالا که تا اینجا اومدیم بگم که ۲ مساله دیگه هم ممکنه موجب نشت حافظه بشه: یکی آزاد نکردن حافظه تو قطعه کدهای مدیریت نشده، و دیگه، استفاده بدون توجه از کلاسهای گرافیکی.
یه نیگاه به اینجا هم بد نیست.
یک راه حل برای این مساله استفاده از Weak Event Patterns است:
http://msdn.microsoft.com/en-us/library/aa970850.aspx
متشکرم.
ضمنا آماده تبادل لینک هستم.
موفق باشید.