PDA

View Full Version : آزاد کردن RAM بعد از بستن فرم



Payman62
چهارشنبه 05 دی 1386, 11:38 صبح
سلام.

من وقتی یه فرم رو میبندم حافظه اشغال شده داخل RAM آزاد نمیشه. چطور باید یه فرم نه کل برنامه رو ببندم تا رم اشغال شده کاملا آزاد شه؟

hassan razavi
چهارشنبه 05 دی 1386, 11:47 صبح
منظورتون از اینکه رم اشغال شده کاملا آزاد نمیشه چیه ؟ احتمالا از یک Refrence (مثلا Image ) استفاده میکنید و بعد از بستن فرم ، نمیتونید از ان استفاده کنید. لطفا مشکل رو جزئی تر مطرح کنید. ولی در کل عملیات آزاد سازی اشیاء در Net. توسط GC (Garbage Collection بصورت خودکار انجام می شود.

Payman62
چهارشنبه 05 دی 1386, 16:35 عصر
سلام.
من برای تست یه آرایه از نوع long به طول 10000000 تعریف کردم. وقتی فرم رو میبستم رم همچنان اشغال میموند. من میخوام بالافاصله بعد از بستن فرم رم آزاد شه.

hassan razavi
پنج شنبه 06 دی 1386, 07:32 صبح
.می تونید از using در هنگام تعریف آرایه استفاده کنید

Payman62
پنج شنبه 06 دی 1386, 20:05 عصر
سلام.
من گفتم آرایه رو برای تست آزاد شدن رم استفاده کردم. مشکل من اصلا آرایه نیست. من میخوام کل فرم بعد از بسته شدن از رم خارج شه نه آرایه.

application_13
شنبه 08 دی 1386, 13:12 عصر
سلام دوست عزیز.
من زیاد وارد نیستم و اگه درست متوجه شده باشم میخوای بعد از بستن برنامه منابعی که توسط برنامه اشغال شده آزاد بشه. اگه منظورتون اینه فکر میکنم باید از

Application.Exit();
استفاده کنید.

vcldeveloper
شنبه 08 دی 1386, 15:15 عصر
من زیاد وارد نیستم و اگه درست متوجه شده باشم میخوای بعد از بستن برنامه منابعی که توسط برنامه اشغال شده آزاد بشه.
وقتی برنامه بسته بشه، فضای حافظه ایی که ویندوز براش در نظر گرفته بود، آزاد میشه، در نتیجه تمام منابعی که در فضای آدرس اون Process تعریف شده باشند هم آزاد میشند. پس کد شما تاثیری در آزاد کردن منابع process نداره.

illegalyasync
شنبه 08 دی 1386, 16:29 عصر
ولی در کل عملیات آزاد سازی اشیاء در Net. توسط GC (Garbage Collection بصورت خودکار انجام می شود


فقط در تئوری اینطور هستش



در نتیجه تمام منابعی که در فضای آدرس اون Process تعریف شده باشند هم آزاد میشند. پس کد شما تاثیری در آزاد کردن منابع process نداره.

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

Payman62
شنبه 08 دی 1386, 17:40 عصر
سلام.
خوب چطور میشه حلش کرد؟
من نمیخوام کل برنامه رو ببندم. فقط یه فرم رو میبندم و منابع اون فرم باید آزاد شه.

alireza1384
یک شنبه 09 دی 1386, 07:56 صبح
پس از ایجاد شی ازنوع فرم و نوشتن دستور show بلافاصله دستور myForm.Dispose() را بنویسید.

Payman62
یک شنبه 09 دی 1386, 11:59 صبح
سلام.
این کار رو هم کرده بودم. dispose هم جواب نمیده.

سار
یک شنبه 09 دی 1386, 13:03 عصر
ممکنه بگی چطور بعد از Dispose کردن کلاس فرمت فهمیدی که فرمت هنوز حافظه رو اشغال کرده؟

اَرژنگ
یک شنبه 09 دی 1386, 13:24 عصر
فقط در تئوری اینطور هستش




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

یک مثال از همینچنین برنامه‌ای بفرتسید.

اَرژنگ
یک شنبه 09 دی 1386, 13:27 عصر
سلام.
خوب چطور میشه حلش کرد؟
من نمیخوام کل برنامه رو ببندم. فقط یه فرم رو میبندم و منابع اون فرم باید آزاد شه.
یک مثال بفرستید که ما هم این مشکل را ببینیم.

Payman62
دوشنبه 10 دی 1386, 00:20 صبح
سلام.
اینم نمونه مشکل جناب آرژنگ.
راستی شما اولین کسی بودی که تو این سایت به من پیغام خصوصی داد. روز دوم عضو شدنم بود که دیدم پیغام دادی. لینک تایپ فارسی رو داده بودی که تو امضاتم هست.

اَرژنگ
دوشنبه 10 دی 1386, 02:57 صبح
سلام.
اینم نمونه مشکل جناب آرژنگ.
راستی شما اولین کسی بودی که تو این سایت به من پیغام خصوصی داد. روز دوم عضو شدنم بود که دیدم پیغام دادی. لینک تایپ فارسی رو داده بودی که تو امضاتم هست.

فینگیلیشی خواندن سخته، برایه همین لینک تایپ فارسی را فرستادم و در امضام هست، ولی تا جائی که میدانم ۳ نفر بیشتر ازش استفاده نمیکنند.

silentrise
دوشنبه 10 دی 1386, 07:08 صبح
دوستان ظاهرا با GCحل میشه ...

Payman62
دوشنبه 10 دی 1386, 18:17 عصر
سلام.
نه این کد مشکلو حل نکرد. بازم رم اشغال میمونه. بعضی مواقع خالی میشه ولی اکثر مواقع نمیشه.

arash1718
دوشنبه 10 دی 1386, 20:50 عصر
اولا بگید که از کجا می فهمید که رمتون آزاد نمیشه.
دوما روی سیستم من وقتی با VS ران می کنم و در شرایط عادی میبندم رمم آزاد میشه ولی اگر به تعداد زیاد اجرا کنم Exception رخ میده که باعث میشه GC درست کار نکنه! که در این شرایط کافیه هندل کنی Exception رو و در Catch این کدارو بذاری:
GC.Collect();
this.Dispose();
سوما اگه Exe شده برنام رو اجرا کنی بازم مشکلی نداره!

hassan razavi
دوشنبه 10 دی 1386, 21:51 عصر
برای من هم مشکلی نداره.

silentrise
دوشنبه 10 دی 1386, 23:11 عصر
سلام
البته فکرکنم دوستمون از PageFileUsage نگاه میکنه تا حدی حرفش درسته از نظر سیستمی دلیلی ندارم براش ولی موضوع جالبیه ادم به یاده قدیم میافته.اون زمان موظف به ازاد کردن رم بودیم انگار الان هم هستیم.

Payman62
سه شنبه 11 دی 1386, 01:59 صبح
سلام.
من که تو پست 15 مثال گذاشتم. شما تست کنید. میبینید رم اشغال میمونه. چه از تو خود C# چه فایل exe. فایلی هم که جناب silentrise گذاشتن مشکلو حل نکرد.

اَرژنگ
سه شنبه 11 دی 1386, 08:40 صبح
سلام.
من که تو پست 15 مثال گذاشتم. شما تست کنید. میبینید رم اشغال میمونه. چه از تو خود C# چه فایل exe. فایلی هم که جناب silentrise گذاشتن مشکلو حل نکرد.
در ثانی این روش استفاده از GC درست نیست!

razavi_university
سه شنبه 11 دی 1386, 11:23 صبح
این کد رو تست کنید
System.Enviroment.Exit(System.Enviroment.ExistCode );//exit from prossec of exicting code

Payman62
سه شنبه 11 دی 1386, 12:29 عصر
سلام.
این کد که کل برنامه رو میبنده دوست عزیز.

سار
سه شنبه 11 دی 1386, 14:10 عصر
لطفن این رو برسی کنید.
فکر می کنم بعد از عمل بسته شدن فرم، کل فرم (کلاس) عملن از حافظه خارج شده باشه.
البته امیدوارم من منظور شما رو درست درک کرده باشم.

Payman62
سه شنبه 11 دی 1386, 14:56 عصر
سلام.
این که همون برنامه ایه که خودم گذاشتم. تغییری توش ندادی.

سار
سه شنبه 11 دی 1386, 15:00 عصر
یک کلاس به شکل زیر بهش اضافه کردم :


using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace Test33
{
publicclass FormControl : System.Windows.Forms.Form
{
public FormControl()
{
}
protected override void OnShown(EventArgs e)
{
this.Text = "Form Controler";
}
protected override void OnClosed(EventArgs e)
{
this.Dispose();
}
}
}


و ازش تو فرم دوم به این شکل استفاده کردم :

public partial class Form2 : FormControl
{
privatelong[] a = newlong[10000000];
public Form2()
{
InitializeComponent();

}
}


این کلاس توش نبود؟
با این حالت تا فرم بسته بشه کل کلاس Dispose میشه و دیگه نباید تو حافظه باشه، درسته؟

Amir Oveisi
سه شنبه 11 دی 1386, 18:41 عصر
دوست عزیز اگه دقت کنین PF Usage بیشتر از یه مقدار خاصی دیگه زیاد نمیشه و این نحوه تصمیم گیری GC هست کی چی رو آزاد کنه
در واقع باز هم حافظه داره مدیریت میشه و به نظر نمیاد مشکلی پیش بیاد

Payman62
سه شنبه 11 دی 1386, 22:50 عصر
سلام.
نه سار کدت جواب نداد. چرا خودتون کدها رو قبل گذاشتن تست نمیکنید؟ خودتم میتونستی چک کنی ببینی رم آزاد نمیشه.

برمودا من که لنگ این نیستم که رم مدیریت میشه یا نه. برای کار من حتما باید بعد از بسته شدن فرم رم آزاد شه.

silentrise
چهارشنبه 12 دی 1386, 05:39 صبح
سلام
ظاهرا این پیج مطالب مفیدی داره در مورد GC صحبت میکنه فکر کنم به خوندنش بارزه!
باسپاس

سار
چهارشنبه 12 دی 1386, 09:38 صبح
سلام.
نه سار کدت جواب نداد. چرا خودتون کدها رو قبل گذاشتن تست نمیکنید؟ خودتم میتونستی چک کنی ببینی رم آزاد نمیشه.

برمودا من که لنگ این نیستم که رم مدیریت میشه یا نه. برای کار من حتما باید بعد از بسته شدن فرم رم آزاد شه.

این یعنی اینکه با عمل Dispose حافظه آزاد نمیشه، درسته؟

در مورد GC هم مثال خود MSDN خیلی جالبه
http://msdn2.microsoft.com/en-us/library/system.gc.aspx

silentrise
چهارشنبه 12 دی 1386, 10:23 صبح
سلام
دوست عزیز اگه میشه در مورد این مثال MSDN توضیح بدین چون این هم ظاهرا رم رو خالی نمیکند
باسپاس

سار
چهارشنبه 12 دی 1386, 13:10 عصر
شما با چه نوع تستس از خارج شدن کلاستون از رم مطلع می شید.
ممکنه کدی قرار بدیدی که حافظه رو قبل از ساخت یک کلاس و بعد از Dispose کردن اون مشخص کنه؟

Payman62
چهارشنبه 12 دی 1386, 18:23 عصر
سلام.
با همون یه آرایه long میشه فهمید دیگه. وقتی رم اشغالی 100 مگ افزایش پیدا میکنه و بعد از بستن فرم و همه اون کارها باز هم رم اشغاله معلومه که آزاد نشده.

Amir Oveisi
چهارشنبه 12 دی 1386, 23:55 عصر
ولی چرا دفعه دوم که فرو 2 رو اجرا میکنی باز هم همون 100 مگ میمونه؟ اگه اونجوری که شما میگین باشه باید با هر بار اجرای فرم 2 100 مگ دیگه هم اشغال شه ولی اینطور نمیشه
در واقع GC با تشخیص این موضوع که اون 100 مگ واسه برنامه شما بوده و دیگه احتیاجی نیست بهش جای همونو میده به اون 100 تای جدید.
ظاهرا هم نمیشه کاریش کرد

Amir Oveisi
پنج شنبه 13 دی 1386, 00:39 صبح
این کد مشکل رو حل کرد دوستان

private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
GC.Collect();
}

Payman62
پنج شنبه 13 دی 1386, 00:39 صبح
سلام.
همیشه این جوری نیست که همون 100 مگ رو بده. بعضی اوقات هم 100 مگ جدید میده و 200 مگ افزایش پیدا میکنه.
بعد هم من کاری ندارم دفعه دوم که فرم باز میشه 100 مگ جدید میده یا نه. واسه من مهمه که بعد از بستن فرم رم آزاد شه. حالا شاید اصلا دیگه فرم رو باز نکنم. ولی رم باید آزاد شه. ولی نمیشه.
عجب مشکل عجیبیه ها. یه رم آزاد کردن که باید جز ساده ترین ویژگی های برنامه باشه تو .net 2005 انجام نمیشه.

Payman62
پنج شنبه 13 دی 1386, 00:45 صبح
سلام.
نه من قبلا تست کردم.
GC.Collect(); هم مشکلو حل نمیکنه.

Amir Oveisi
پنج شنبه 13 دی 1386, 00:48 صبح
اگه یه بار باز کنی و ببندی بعضی وقتا کار نمیکنه
ولی اگه دفعه دوم که بازش میکنی و میبندی نگاه کنی میبینی کامل آزاد میشه
به نظر من باید تو کلاس GC دنبال جواب باشیم

Amir Oveisi
پنج شنبه 13 دی 1386, 20:38 عصر
اینم جواب کامل این مشکل :


class MyClass : IDisposable
{
public long[] a = new long[10000000];

public void Dispose()
{
a = new long[0];
GC.Collect();
}


}


public partial class Form2 : Form
{
MyClass m = new MyClass();
public Form2()
{
InitializeComponent();
}

private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
m.Dispose();
}
}

برنامه کاملشو اینجا گذاشتم

Payman62
یک شنبه 16 دی 1386, 00:57 صبح
سلام.
برمودا کد جالبی بود. رم رو آزاد میکنه. ولی به ازای هر فرمی که باز میکنیم حدود یکی دو مگ رم اشغال میمونه. یعنی مثلا 10 بار فرم رو باز کنیم و بعد همه رو ببندیم رم آزاد میشه ولی حدود 20 مگ اشغال میمونه.

Payman62
سه شنبه 18 دی 1386, 12:46 عصر
سلام.
برمودا شما آرایه رو تو کلاس تعریف کردی. اگه من بخوام تو خود فرمم تعریف کنم این روش جواب نمیده.
کسی روش دیگه ای به ذهنش نمیرسه؟

Amir Oveisi
چهارشنبه 19 دی 1386, 00:20 صبح
چه اجباری هست که تو فرم تعریف بشه؟!!!

Amir Oveisi
چهارشنبه 19 دی 1386, 00:29 صبح
در ضمن با این کد اگه تو فرم هم تعریف بشه جواب میده :


public partial class Form2 : Form
{
public int[] a = new int[10000000];
// MyClass m = new MyClass();
public Form2()
{
InitializeComponent();
}

private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
//m.Dispose();
a = new int[0];
GC.Collect();
}
}

vcldeveloper
چهارشنبه 19 دی 1386, 03:24 صبح
ولی به ازای هر فرمی که باز میکنیم حدود یکی دو مگ رم اشغال میمونه. یعنی مثلا 10 بار فرم رو باز کنیم و بعد همه رو ببندیم رم آزاد میشه ولی حدود 20 مگ اشغال میمونه.
از چه طریقی چک می کنید که مقدار RAM اشغالی چه مقدار هست؟
اگه از Task Manager ویندوز استفاده می کنید، عددی که بهتون نشون میده چندان قابل اطمینان نیست، چون وقتی برنامه حافظه ایی را آزاد میکنه، به سرعت اون حافظه به ویندوز برگشت داده نمیشه، بلکه بصورت Allocated برای اون Process باقی می مونه تا زمانی که یا خود Process ازش استفاده کنه، یا ویندوز اونو نیاز داشته باشه. برای بررسی وضعیت مصرف حافظه برنامه از ابزارهایی که برای این کار تولید شدند استفاده کنید.

سار
چهارشنبه 19 دی 1386, 08:31 صبح
از چه طریقی چک می کنید که مقدار RAM اشغالی چه مقدار هست؟
اگه از Task Manager ویندوز استفاده می کنید، عددی که بهتون نشون میده چندان قابل اطمینان نیست، چون وقتی برنامه حافظه ایی را آزاد میکنه، به سرعت اون حافظه به ویندوز برگشت داده نمیشه، بلکه بصورت Allocated برای اون Process باقی می مونه تا زمانی که یا خود Process ازش استفاده کنه، یا ویندوز اونو نیاز داشته باشه. برای بررسی وضعیت مصرف حافظه برنامه از ابزارهایی که برای این کار تولید شدند استفاده کنید.

باور کنید من هم از وقتی این تاپیک شروع شده دارم دنبال جواب همین سوال می گردم.:قلب:

Payman62
چهارشنبه 19 دی 1386, 12:18 عصر
سلام.
برمودا جان من که فقط نمیخوام یه آرایه تعریف کنم که تو کلاس تعریف کنم یا تو form closing بیام مقدارش رو 0 کنم. کلی متغیر هست و همشون هم تو فرمم هستن و با اشیا فرم ارتباط دارن. میشه برد تو کلاس ولی من میخوام بدونم وقتی داخل فرم هستن و فرم بسته میشه چطور میشه رم رو آزاد کرد. آرایه رو فقط برای تست مثال زدم.

جناب کشاورز من هم همینو میگم. میگم رم آزاد نمیشه و من میخوام با کد نویسی بلافاصله آزادش کنم.

سار جان از زحمات شما هم ممنونم.

Amir Oveisi
چهارشنبه 19 دی 1386, 23:57 عصر
دوست عزیز باید بنابه اون کاری که میخواین انجام بدین یه روشی پیدا کنین که بشه باهاش Memory رو آزاد کرد (البته PageFile بگم بهتره )
ولی بر اساس ساختار کلاس ها اگه شما این کارو با طراحی کلاس ها انجام بدین بهتر نتیجه خواهید گرفت
(در کل 90% یه روش مطلق واسه این کاری که شما میگین وجود نداره )
اگر نظر من موردی داشت خوشحال میشم اطلاعات کامل تری بگیرم از دوستان

Payman62
پنج شنبه 20 دی 1386, 17:14 عصر
سلام.
راستش برنامه من کلاینت سروریه.
تو این تاپیک مشکلمو مطرح کردم ولی جواب نگرفتم.
http://barnamenevis.org/forum/showthread.php?t=88885
خلاصه مشکلم اینه که وقتی ارتباط برقرار میشه و بعد که دیسکانکت کنم دیگه نمیتونم همون پورت رو باز کنم. برمودا فکر کنم این سوال رو تو یاهو هم ازت پرسیده بودم.
خیلی هم سرچ کردم ولی کدی برای حل مشکلم پیدا نکردم.

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

حالا شما بگید چی کار کنم.