SajjadKhati (24-10-21), Speed Racer (25-10-21)
با سلام،
بنده چند تا نکته به این بحث اضافه کنم که شاید کمک بیش تری به دوستانی بکنه که به مشکل مشابه بر می خورن:
۱− تابع Dispose توسط برنامه نویس نوشته میشه (و نه این اینکه توسط JIT Compiler به شکل خودکار ایجاد بشه) و هدفش اینه که منابع Unmanaged رو پاک کنه (سجاد هم بار ها بهش اشاره کرد). پس برنامه نویس موظفه که اگه کلاسی می نویسه که منابع بومی داره، از اینترفیس IDisposable پیروی کنه و تابع Dispose رو به شکلی پیدا سازی کنه که منابع بومی رو پاک کنه. مضافا بر اون برخلاف Finalizer که به شکل خودکار در آخر عمر اشیا صدا زده میشه، تابع Dispose باید به صراحت توسط کد صدا زده بشه وگرنه کسی دیگه این کار رو نمی کنه.
۲− کنترل PictureBox عکس های رو که بهش اختصاص داده میشن ذخیره نمی کنه. تو تمام مثال های مطرح شده در این تاپیک وقتی شما عکس رو به PictureBox تخصیص میدید، عکس قبلی دیگه به پایان عمر خودش میرسه و دیر یا زود توسط GC جمع آوری میشه. نکته اینه که اگه نگاهی به سورس دات نت بیاندازید، GC پس از مدتی منابع بومی و هم منابع غیر بومی شی Bitmap رو آزاد می کنه (حالا ممکنه این روند در حالت شما تا زمانی طول بکشه که میزان حافظه به حدود ۹۰۰ مگابایت برسه).
۳− این که چرا Refresh کردن فرم به آزادسازی حافظه کمک می کنه بنده نمی تونم دلیلی براش بیارم. این متد دو دستور لایه پایین رو اجرا می کنه که یکیش مستقیما به کرنل هستش. یه احتمال می تونه این باشه چون تمام بچه های فرم بی اعتبار میشن و مجاورت فضای Heap مربوط به PictureBox (به عنوان یکی از بچه های فرم) هم نامعتبره، کل عکس های قبلی که در اون مجاورت تخصیص پیدا کرده بودن (امیدوارم حداقل ویندوز عقلش رسیده باشه که این کار رو بکنه) به یک باره آزاد میشن. میشه این فرضیه رو تست کرد.
۴− صدا زدن صریح GC.Collect عموما کار درستی نیست. نکته اینه که شما با این کار اشیای نسل صفرم تا نسل دوم رو پاک می کنید. این در حالیه که عناصر گرافیکی معمولا برای مدت طولانی تری در نسل دوم می مونن تا در فرخوانی های بعدی دات نت مجبور نباشه اونا رو ایجاد کنه ولی شما با این کار هر چی دات نت رشته کرده بود رو پنبه می کنید. جدای از اون، نشت حافظه تنها به معنای افزایش افسار گسیخته ی حافظه نیست بلکه شامل مفهمومی به نام GC Pressure هم میشه که شما با فرخوانی GC.Collect در هر ۱۷ میلی ثانیه می تونید به اون دامن بزنید.
۵− مخزن کد EmguCV همین مثال رو به شکل Zero Copy پیدا کرده (که روش درستش هم هست چون لایه ی پایین OpenCV دقیقا این طوری کار می کنه). متاسفانه بنده در حال حاضر ابزاری ندارم که این کد رو تست کنم ولی احتمالا اصلا هیچ مشکل حافظه ای به وجود نیاره.
'چو ایران نباشد، تن من مباد
Dim Armin As Iranian
If Iran.Enabled = False Then Armin.Enabled = False
SajjadKhati (24-10-21), Speed Racer (25-10-21)
1 کاربر در حال مشاهده این موضوع. (0 عضو و 1 میهمان)
Bookmarks