PDA

View Full Version : سوال: مشکل کمبود حافظه در نمایش تصاویر با رزولوشن بالا و عدم آزادسازی منابع با GC و Dispose کردن اشیا



amir_pro
جمعه 01 خرداد 1394, 11:44 صبح
سلام دوستان

مشکلی که تو wpf بهش برخوردم اینه که اگر قرار باشد تعدادی تصویر مثلا 400 طبق رویدادی مثلا حرکت موس تغییر کنند بعد از مدتی برنامه با کمبود حافظه مواجه می شود و مشخصه که پیغام خطای زیر An unhandled exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll

Additional information: A generic error occurred in GDI+.

فرمت تصاویر به صورتی هست که برای نشون دادنشون از کلاسهای Bitmap و BitmapSource مجبورم استفاده کنم و در نهایت شی ساخته شده از کلاس BitmapSource را به خاصیت Source آبجکت Image بایند میکنم

خطی که باعث گرفتن حافظه میشه خط زیر است:
image2Show.Source = output;



سورس تصویر را null کردم و از GC استفاده کردم حافظه را آزاد نمیکنه. همه متغیرها که به صورت محلی برای نمایش تصاویر استفاده شده را dispose کردم باز حافظه آزاد نمیشه

اینم میدونم که تا وقتی از داخل برنامه به یک آبجکت لینکی وجود داشته باشه GC عمل نمیکنه


خیلی جستجو کردم اما هنوز به راه حلی نرسیدم

اینم سورس برنامه:
System.Drawing.Bitmap bmp = presentationImage.DrawToBitmap(width, height);

BitmapSource output = System.Windows.Interop.Imaging.CreateBitmapSourceF romHBitmap(bmp.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromWidthAndHeight(width, height));

image2Show.Source = output;


width و height نشون دهنده رزولوشن است که 512 گذاشتم

RmeXXXXXXXXX
جمعه 01 خرداد 1394, 15:40 عصر
من درست درست متوجه منظورتون نشدم
ولی در در کل اگه درست متوجه شده باشم مشکل کمبود حافظه پیدا میکنین؟ (دلیل خطا شاید چیز دیگه ای هم باشه. OutOfMemoryExceptionفکر کنم برا پرشدن heap صادر میشه! StackOverFlowException هم که برا استک)
به هرحال:
شما تا میتونید از تصاویر ایجاد شده قبلی استفاده کنین. یعنی یه تصویر رو ک لود کردین از همون تا میتونید استفاده کنید.
شما همچنین میتونید از ارجاع ضعیف هم استفاده کنید یعنی تصاویر رو توی حافظه بارکنید ولی همزمان به GC اجازه بدین که اگر کمبود حافظه پیدا کرد این اشیاء رو Dispose کنه.
آدرس زیر:
http://www.rwejahad.blogfa.com/post/35
ا

RmeXXXXXXXXX
جمعه 01 خرداد 1394, 15:43 عصر
آدرس زیر هم نحوه استفاده از کلاس جنریک System.WeakReference<T> رو توضیح میده که البته برا دانت فریم ورک ورژن 4.5 به بعد هستش.
http://www.blackwasp.co.uk/WeakReferenceT.aspx

amir_pro
جمعه 01 خرداد 1394, 17:28 عصر
مشکل از GetHbitmap بود که با ایمپورت کردن gdi32.dll و استفاده از تابع DeleteObject مشکل حل شد