ورود

View Full Version : Memory Leak Wpf !



Alirezanet
سه شنبه 24 تیر 1393, 02:57 صبح
سلام
مدتیه به مشکلی خوردم گفتم شاید کسی قبلا جوابی براش پیدا کرده باشه ...
نرم افزار هایی که تا الان با Wpf نوشتم ظاهرا نشتی مموری دارند ! و نمیدونم دقیق مشکل از کجاست ! ...
کدهایی که من نوشته بودم تماما Dispose میشه و توی حافظه نمیمونه ولی پنجره های Wpf بعد از باز شدن مقداری از فضا رو اشغال میکنند و اون فضا بعد از بسته شدن پنجره آراد نمیشه !
به خصوص این مشکل جایی خودش رو نشون میده که از کامپوننتی مثل Devexpress هم استفاده کنی ... الان یکی از نرم افزار هام به شکلی شده که با باز کردن هر پنجره جدید 6-10 مگابایت مموری اشغال میشه و بعد از بسته شدن پنجره آزاد نمیشه !!
با دلایل بروز Memort Leak هم کاملا آشنام و تمام موارد رو بررسی کردم و مشکلی نبود (مثل EventHandlers و Binding و... )

برای تست میتونید یک Wpf Application بسازید و یک باتن در فرم اصلی(MainWindow) قرار بدید که فرم دیگری (ChildWindow) رو باز کنه ... بعد از اینکه فرم (ChildWindow) رو میبندیم فضای اختصاص داده شده آزاد نمیشه !!

پشنهادی دارید این مشکل رو برطرف کنم ؟!

Esikhoob
سه شنبه 24 تیر 1393, 13:14 عصر
با سلام

فکر نمیکنم از این پدیده بشود نتیجه گرفت که Memory Leak اتفاق افتاده ، چون در خیلی برنامه های باکیفیت دیگر هم از اینطور اتفاق ها زیاد میافتد.
مثلا برنامه VisualStudio2013 ، اول بازکردن 200MB حافظه اشغال میکند و اگر یک پروژه را باز کنی که در آن حالت مقدار استفاده از حافظه زیادتر میشود و بعد آن پروژه را ببندی ، مقدار حافظه به مقدار اولیه (200MB) بر نمیگردد.

Alirezanet
سه شنبه 24 تیر 1393, 20:23 عصر
فرمایش شما درسته وبا توجه به تحقیقاتی که توی این زمینه کردم به نظر میرسه در این موارد GC دات نت سعی میکنه اطلاعات رو تا جای ممکن توی حافظه نگه داره برای استفاده مجدد از منابع و زمانی که با کمبود مموری مواجه بشه سیستم کم کم این موارد رو از حافظه خارج میکنه ... به همین دلیل هست کلا پیشنهاد شده در برنامه های دات نتی نگران Memory Leak نباشیم مگر اینکه خودمون توی ایجاد شدنش دخالت داشته باشیم ...
ولی مدیریت GC از نظر مشتری شاید منطقی به نظر نیاد و الان اونها با توجه به اینکه C++‎‎‎‎‎‎ کار هم هستند تصور میکنند Memory Leak شدیدی داره نرم افزارهای Wpf ...
به هر حال باید راهی باشه که این استفاده از مموری رو توی Wpf خودمون کنترل کنیم تا حدودی ...

نگه داشتن 1 بار اطلاعات هر پنجره توی حافظه برای استفاده مجدد در مموری منطقی به نظر میرسه ... ولی مشکلی که الان من باهاش سروکار دارم اینه که پس از یاز شدن یک پنجره به دفعات در هر بار باز شدن این فضا از مموری داره اشغال میشه که منطقی به نظر نمیرسه ... و باید به نحوی نهایتا 1 بار این اطلاعات در مموری کش بشه.
(البته نا گفته نماند این مشکل دوم که گفتم بیشتر زمان استفاده از کامپوننت هایی مثل Devexpress خودش رو نشون میده که توی تمام فروم هاشون گفتند که مموری لیک ندارند)

در آخر از اینکه از نظراتتون مارو بهره مند میکنید تشکر میکنم.

aghayex
پنج شنبه 26 تیر 1393, 17:12 عصر
GC ویژوال در مدیریت حافظه کم کاری می کنه و این در برنامه های wpf خودشو به خوبی نشون میده .
یه کد دارم که می تونی حافظه رو از داده های بلا استفاده خالی کنی .

Alirezanet
جمعه 27 تیر 1393, 03:43 صبح
cg ویژوال در مدیریت حافظه کم کاری می کنه و این در برنامه های wpf خودشو به خوبی نشون میده .
یه کد دارم که می تونی حافظه رو از داده های بلا استفاده خالی کنی .

به هر حال بهتر از هیچیه ... ولی کد رو نذاشتین !؟ لایسنس داره ؟ :لبخندساده:
البته اون هم GC هست که مخفف Garbage collection هستش ... (میدونم اشتباه تایپی بود برای اطلاع دوستان گفتم).

با تشکر

aghayex
جمعه 27 تیر 1393, 04:23 صبح
loprocess=System.Diagnotis.Process.GetCurreentProc ess();
try
{
loprocess.MaxWorkingSet=(IntPtr)((int)loprocess.Ma xWorkingSet);
loprocess.MinWorkingSet=(IntPtr)((int)loprocess.Mi nWorkingSet);
}
catch(Exception er)
{
}

Alirezanet
جمعه 27 تیر 1393, 15:36 عصر
loprocess=System.Diagnotis.Process.GetCurreentProc ess();
try
{
loprocess.MaxWorkingSet=(IntPtr)((int)loprocess.Ma xWorkingSet);
loprocess.MinWorkingSet=(IntPtr)((int)loprocess.Mi nWorkingSet);
}
catch(Exception er)
{
}


سلام ممنون ازتون ولی این کد برای تغییر WorkingSet هستش که فقط Pagefile های ویندوز رو تغییر میده و ربطی به GC نداره ! !
من از مشابه این کد بعضی از جاها برای نمایش MemoryUsage برنامه ها به صورت Fake استفاده میکنم. که در کل استفاده ازش کار دستی نیست و Performance برنامه کاهش پیدا میکنه و به مموری سیستم فشار میاد.

aghayex
شنبه 28 تیر 1393, 11:18 صبح
در یه برنامه هنگام گزارش گیری با استیمول خیلی اون برنامه حافظه ی زیادی رو اشغال می کرد و حتی زمانی که صفحه گزارش رو می بستم باز GC حافظه رو رها نمی کرد که در نهایت مجبور می شدو از این کد استفاده کنم

majid325
چهارشنبه 08 مرداد 1393, 15:47 عصر
با دلایل بروز Memort Leak هم کاملا آشنام و تمام موارد رو بررسی کردم و مشکلی نبود (مثل EventHandlers و Binding و... )

در دات نت همچین چیزی نداریم(Memort Leak)
وقتی شما ابجکتی رو در دات نت dispose میکنید ، دلیل بر این نیست که همون موقع dispose بشه، خود دات نت تصمیم میگیره که کی dispose بشه.
ا

Alirezanet
پنج شنبه 09 مرداد 1393, 09:48 صبح
در دات نت همچین چیزی نداریم(Memort Leak)
وقتی شما ابجکتی رو در دات نت dispose میکنید ، دلیل بر این نیست که همون موقع dispose بشه، خود دات نت تصمیم میگیره که کی dispose بشه.
ا
فرمایش شما از این جهت که خود دات نت داره کار مدیریت مموری رو انجام میده و خودش منابع رو آزاد میکنه درسته ولی توی مباحث نرم افزار نمیشه گفت این مورد وجود نداره کلا ! وجود داره ولی مدیریتش دست ما نیست ...
من هم دقیق به همین دلیل میخواستم مدیریت این قسمت رو به عهده بگیرم و GC رو کنترل کنم. راه هایی زیادی هم تو فروهای دیگه پیشنهاد دادند(stackoverflow- Msdn) برای رفع این مشکل ولی هنوز به نتیجه ای نرسیدم که کاربردی باشه. راه حلی پیدا شد در اختیار دوستان میزارم. شما هم به جای تعویض صورت مسئله اگر راه حلی پیدا کردین قرار بدید بهتره.
با تشکر