PDA

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



NiMble_m
سه شنبه 18 مهر 1391, 09:52 صبح
سلام
من یک برنامه دارم که 5 تا فرم داره
یکی از فرم های برنامه خیلی سنگین شده
به طوری که وقتی باز میشه 300 مگابایت از حافظه رو میگیره
و وقتی میبندم این 300 مگابایت آزاد نمیشه
حتی از متد Dispose هم استفاده کردم ولی باز هم حافظه به سیستم برگشت نمیشه
لطفا راهنمایی کنید

morteza271
سه شنبه 18 مهر 1391, 10:31 صبح
شما چه کردین با اون فرم!!!!!!!!!!!!!!!!!!!!!!
بعد اون فرم چقد طول میکشه باز شدنش!اعصابتون داغون نمیشه؟؟!!

تا جایی که من میدونم بعد از بسته شدن بکل برنامه حافظه اختصاص داده شده آزاد میشه مگر اینکه خودتون دستی این کار رو بکنید.
برای اینکار یه جستجو به زبان انگلیسی بزنید خیلی زود به جواب میرسین. مثلا میتونید این عبارت رو جستجو کنید :
how to release memory in C#‎

من الان نمیتونم وگرنه حتما خودم جستجو میکردم و نتیجه رو واستون میذاشتم!
موفق باشید

RIG000
سه شنبه 18 مهر 1391, 11:15 صبح
حالا من یه چی بگم ؟ از theard و backgrandworker میتونید استفاده کنید. من خودم notresponding داشتم واسه فرمم که از worker استفاده کردم و نتیجه هم داشت . واسه لود گریدم اینکارو کردم. اگه مشکلتون اینه که اسنجوری حل میشه.

danialafshari
سه شنبه 18 مهر 1391, 11:59 صبح
سلام دوست عزیز
برای خروج از این کد استفاده کن ببین کارت راه میفته !
Application.ExitThread();
موفق باشی

hellboyfa
سه شنبه 18 مهر 1391, 12:13 عصر
سلام
من یک برنامه دارم که 5 تا فرم داره
یکی از فرم های برنامه خیلی سنگین شده
به طوری که وقتی باز میشه 300 مگابایت از حافظه رو میگیره
و وقتی میبندم این 300 مگابایت آزاد نمیشه
حتی از متد Dispose هم استفاده کردم ولی باز هم حافظه به سیستم برگشت نمیشه
لطفا راهنمایی کنید

سلام ببین با این کار حتما کارت راه میفته چون 100% جواب داده !


public static void FlushMemory()
{
System.Diagnostics.Process prs = System.Diagnostics.Process.GetCurrentProcess();
try
{
prs.MinWorkingSet = (IntPtr)(300000);
}
catch { }
}
private void timer2_Tick(object sender, EventArgs e)
{
FlushMemory();
}

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


1. پس از هر عملیاتی که شما شیئی جدید می سازید و یا آنرا حذف می کنید. (Dispose)


2. به طور مستمر بوسیله تایمری که بر روی Interval خاصی تنظیم شده باشد. (مثلا 2000 میلی ثانیه)


در هر حال پس از فراخوانی این تابع شما خواهید دید که حافظه تخصیص داده شده برای برنامه شما بطور شگفت انگیزی تغییر خواهد کرد و در واقع پویا خواهد شد.

NiMble_m
سه شنبه 18 مهر 1391, 12:45 عصر
من یه عکس دارم که حجمش بالاست
اینو داخل فرم لود میکنم حافظه مصرفی میرسه به 300 مگابایت
ولی تا قبل از لود عکس حافظه مصرفی 20 مگابایته
ولی وقتی بعدش یک عکس کوچیک لود میکنم حافظه مصرفی همون 300 مگابایت میمونه
من موندم چرا خود سیستم عامل عکس قبلی رو از حافظه حذف نمیکنه

NiMble_m
سه شنبه 18 مهر 1391, 12:50 عصر
دوست عزیز hellboyfa (http://barnamenevis.org/member.php?190063-hellboyfa) واقعا دمت گرم
خیلی باحال بود
یعنی اینو هیج جا پیدا نکرده بودم
جالب اینجاست که قبل از لود کردن عکس حافظه مصرفی 20 مگابایت بود بعد از لود کردن شد 300 مگابایت و بعد از بستن فرم و اجرای این تابع حافظه مصرفی شد 5 مگابایت یعنی از قبلش هم کمتر
واقعا ممنونم
فقط من موندم که چرا زیر پاسخ شما دکمه تشکر کردن وجود نداره؟؟؟؟؟؟

morteza271
سه شنبه 18 مهر 1391, 12:57 عصر
پاسخ و راه حل جالبی بود!
فقط میشه لطف کنید توضیح بدین این خط از کدتون چیکار میکنه و اون 300000 چیه؟؟
prs.MinWorkingSet = (IntPtr)(300000);

بازم ممنون

RIG000
سه شنبه 18 مهر 1391, 13:51 عصر
سلام ببین با این کار حتما کارت راه میفته چون 100% جواب داده !


public static void FlushMemory()
{
System.Diagnostics.Process prs = System.Diagnostics.Process.GetCurrentProcess();
try
{
prs.MinWorkingSet = (IntPtr)(300000);
}
catch { }
}
private void timer2_Tick(object sender, EventArgs e)
{
FlushMemory();
}

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


1. پس از هر عملیاتی که شما شیئی جدید می سازید و یا آنرا حذف می کنید. (Dispose)


2. به طور مستمر بوسیله تایمری که بر روی Interval خاصی تنظیم شده باشد. (مثلا 2000 میلی ثانیه)


در هر حال پس از فراخوانی این تابع شما خواهید دید که حافظه تخصیص داده شده برای برنامه شما بطور شگفت انگیزی تغییر خواهد کرد و در واقع پویا خواهد شد.

من یه برنامه داشتم که 178 مصرف رمش هست اینو اجرا کردم اما همون 178 موند . اینتروال تایمر رو باید تغییر بدم. در شمن true هستش enable ....
موندم چرا تغییر پذیری نداره.

NiMble_m
سه شنبه 18 مهر 1391, 16:16 عصر
نه عزیزم
فقط کافیه که بعد از لود کامل فرم این کار رو انجام بدی
نیازی نیست حتما داخل تایمر باشه
دقت کن که این یه تابع هستش و هر جایی قابل استفاده هستش
پس حتما نباید داخل تایمر باشه

RIG000
سه شنبه 18 مهر 1391, 16:38 عصر
میدونم . گفتم شاد با تایمر انجام میشه ......
به هر حال در اون صورت هم به نتیجه نرسیده بودم.

morteza271
سه شنبه 18 مهر 1391, 16:49 عصر
شما کد زیر رو در صفحه اول برنامتون بنویسید، ببینید که کارایی داره یا نه!!!
public MainForm()
{
InitializeComponent();

Timer timerMemory = new Timer();
timerMemory.Interval = 60000;
timerMemory.Tick += new EventHandler(timerMemory_Tick);
timerMemory.Enabled = true;
timerMemory.Start();
}
public static void FlushMemory()
{
System.Diagnostics.Process prs = System.Diagnostics.Process.GetCurrentProcess();
try
{
MessageBox.Show("1");
prs.MinWorkingSet = (IntPtr)(300000);
MessageBox.Show("2");
}
catch { }
}
private void timerMemory_Tick(object sender, EventArgs e)
{
FlushMemory();
}

وقتی که پیام شماره 1 اومد فضای اختصاص یافته رو نگاه کن و بعد ok بزن و بعد که پیام 2 اومد دوباره فضا رو مقایسه کنن. ببین نتیجه داره یا نه!!!!!!
موفق باشید