سلام.
من وقتی یه فرم رو میبندم حافظه اشغال شده داخل RAM آزاد نمیشه. چطور باید یه فرم نه کل برنامه رو ببندم تا رم اشغال شده کاملا آزاد شه؟
Printable View
سلام.
من وقتی یه فرم رو میبندم حافظه اشغال شده داخل RAM آزاد نمیشه. چطور باید یه فرم نه کل برنامه رو ببندم تا رم اشغال شده کاملا آزاد شه؟
منظورتون از اینکه رم اشغال شده کاملا آزاد نمیشه چیه ؟ احتمالا از یک Refrence (مثلا Image ) استفاده میکنید و بعد از بستن فرم ، نمیتونید از ان استفاده کنید. لطفا مشکل رو جزئی تر مطرح کنید. ولی در کل عملیات آزاد سازی اشیاء در Net. توسط GC (Garbage Collection بصورت خودکار انجام می شود.
سلام.
من برای تست یه آرایه از نوع long به طول 10000000 تعریف کردم. وقتی فرم رو میبستم رم همچنان اشغال میموند. من میخوام بالافاصله بعد از بستن فرم رم آزاد شه.
.می تونید از using در هنگام تعریف آرایه استفاده کنید
سلام.
من گفتم آرایه رو برای تست آزاد شدن رم استفاده کردم. مشکل من اصلا آرایه نیست. من میخوام کل فرم بعد از بسته شدن از رم خارج شه نه آرایه.
سلام دوست عزیز.
من زیاد وارد نیستم و اگه درست متوجه شده باشم میخوای بعد از بستن برنامه منابعی که توسط برنامه اشغال شده آزاد بشه. اگه منظورتون اینه فکر میکنم باید از
Application.Exit();
استفاده کنید.
وقتی برنامه بسته بشه، فضای حافظه ایی که ویندوز براش در نظر گرفته بود، آزاد میشه، در نتیجه تمام منابعی که در فضای آدرس اون Process تعریف شده باشند هم آزاد میشند. پس کد شما تاثیری در آزاد کردن منابع process نداره.نقل قول:
من زیاد وارد نیستم و اگه درست متوجه شده باشم میخوای بعد از بستن برنامه منابعی که توسط برنامه اشغال شده آزاد بشه.
فقط در تئوری اینطور هستشنقل قول:
ولی در کل عملیات آزاد سازی اشیاء در Net. توسط GC (Garbage Collection بصورت خودکار انجام می شود
بعضی از برنامه ها مموری مپد فایل دارن یا هندل های مختلفی دارن که درست بسته نمیشن و بعد از ترمینیت شدن پروسه بازم حافظه رو نگه میدارن قرار نیست که این اتفاق بیفته اما در عمل میبینی که میفتهنقل قول:
در نتیجه تمام منابعی که در فضای آدرس اون Process تعریف شده باشند هم آزاد میشند. پس کد شما تاثیری در آزاد کردن منابع process نداره.
سلام.
خوب چطور میشه حلش کرد؟
من نمیخوام کل برنامه رو ببندم. فقط یه فرم رو میبندم و منابع اون فرم باید آزاد شه.
پس از ایجاد شی ازنوع فرم و نوشتن دستور show بلافاصله دستور myForm.Dispose() را بنویسید.
سلام.
این کار رو هم کرده بودم. dispose هم جواب نمیده.
ممکنه بگی چطور بعد از Dispose کردن کلاس فرمت فهمیدی که فرمت هنوز حافظه رو اشغال کرده؟
سلام.
اینم نمونه مشکل جناب آرژنگ.
راستی شما اولین کسی بودی که تو این سایت به من پیغام خصوصی داد. روز دوم عضو شدنم بود که دیدم پیغام دادی. لینک تایپ فارسی رو داده بودی که تو امضاتم هست.
دوستان ظاهرا با GCحل میشه ...
سلام.
نه این کد مشکلو حل نکرد. بازم رم اشغال میمونه. بعضی مواقع خالی میشه ولی اکثر مواقع نمیشه.
اولا بگید که از کجا می فهمید که رمتون آزاد نمیشه.
دوما روی سیستم من وقتی با VS ران می کنم و در شرایط عادی میبندم رمم آزاد میشه ولی اگر به تعداد زیاد اجرا کنم Exception رخ میده که باعث میشه GC درست کار نکنه! که در این شرایط کافیه هندل کنی Exception رو و در Catch این کدارو بذاری:
GC.Collect();
this.Dispose();
سوما اگه Exe شده برنام رو اجرا کنی بازم مشکلی نداره!
برای من هم مشکلی نداره.
سلام
البته فکرکنم دوستمون از PageFileUsage نگاه میکنه تا حدی حرفش درسته از نظر سیستمی دلیلی ندارم براش ولی موضوع جالبیه ادم به یاده قدیم میافته.اون زمان موظف به ازاد کردن رم بودیم انگار الان هم هستیم.
سلام.
من که تو پست 15 مثال گذاشتم. شما تست کنید. میبینید رم اشغال میمونه. چه از تو خود C# چه فایل exe. فایلی هم که جناب silentrise گذاشتن مشکلو حل نکرد.
این کد رو تست کنید
System.Enviroment.Exit(System.Enviroment.ExistCode );//exit from prossec of exicting code
سلام.
این کد که کل برنامه رو میبنده دوست عزیز.
لطفن این رو برسی کنید.
فکر می کنم بعد از عمل بسته شدن فرم، کل فرم (کلاس) عملن از حافظه خارج شده باشه.
البته امیدوارم من منظور شما رو درست درک کرده باشم.
سلام.
این که همون برنامه ایه که خودم گذاشتم. تغییری توش ندادی.
یک کلاس به شکل زیر بهش اضافه کردم :
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 میشه و دیگه نباید تو حافظه باشه، درسته؟
دوست عزیز اگه دقت کنین PF Usage بیشتر از یه مقدار خاصی دیگه زیاد نمیشه و این نحوه تصمیم گیری GC هست کی چی رو آزاد کنه
در واقع باز هم حافظه داره مدیریت میشه و به نظر نمیاد مشکلی پیش بیاد
سلام.
نه سار کدت جواب نداد. چرا خودتون کدها رو قبل گذاشتن تست نمیکنید؟ خودتم میتونستی چک کنی ببینی رم آزاد نمیشه.
برمودا من که لنگ این نیستم که رم مدیریت میشه یا نه. برای کار من حتما باید بعد از بسته شدن فرم رم آزاد شه.
سلام
ظاهرا این پیج مطالب مفیدی داره در مورد GC صحبت میکنه فکر کنم به خوندنش بارزه!
باسپاس
این یعنی اینکه با عمل Dispose حافظه آزاد نمیشه، درسته؟
در مورد GC هم مثال خود MSDN خیلی جالبه
http://msdn2.microsoft.com/en-us/library/system.gc.aspx
سلام
دوست عزیز اگه میشه در مورد این مثال MSDN توضیح بدین چون این هم ظاهرا رم رو خالی نمیکند
باسپاس
شما با چه نوع تستس از خارج شدن کلاستون از رم مطلع می شید.
ممکنه کدی قرار بدیدی که حافظه رو قبل از ساخت یک کلاس و بعد از Dispose کردن اون مشخص کنه؟
سلام.
با همون یه آرایه long میشه فهمید دیگه. وقتی رم اشغالی 100 مگ افزایش پیدا میکنه و بعد از بستن فرم و همه اون کارها باز هم رم اشغاله معلومه که آزاد نشده.
ولی چرا دفعه دوم که فرو 2 رو اجرا میکنی باز هم همون 100 مگ میمونه؟ اگه اونجوری که شما میگین باشه باید با هر بار اجرای فرم 2 100 مگ دیگه هم اشغال شه ولی اینطور نمیشه
در واقع GC با تشخیص این موضوع که اون 100 مگ واسه برنامه شما بوده و دیگه احتیاجی نیست بهش جای همونو میده به اون 100 تای جدید.
ظاهرا هم نمیشه کاریش کرد
این کد مشکل رو حل کرد دوستان
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
GC.Collect();
}
سلام.
همیشه این جوری نیست که همون 100 مگ رو بده. بعضی اوقات هم 100 مگ جدید میده و 200 مگ افزایش پیدا میکنه.
بعد هم من کاری ندارم دفعه دوم که فرم باز میشه 100 مگ جدید میده یا نه. واسه من مهمه که بعد از بستن فرم رم آزاد شه. حالا شاید اصلا دیگه فرم رو باز نکنم. ولی رم باید آزاد شه. ولی نمیشه.
عجب مشکل عجیبیه ها. یه رم آزاد کردن که باید جز ساده ترین ویژگی های برنامه باشه تو .net 2005 انجام نمیشه.
سلام.
نه من قبلا تست کردم.
GC.Collect(); هم مشکلو حل نمیکنه.
اگه یه بار باز کنی و ببندی بعضی وقتا کار نمیکنه
ولی اگه دفعه دوم که بازش میکنی و میبندی نگاه کنی میبینی کامل آزاد میشه
به نظر من باید تو کلاس GC دنبال جواب باشیم
اینم جواب کامل این مشکل :
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();
}
}
برنامه کاملشو اینجا گذاشتم
سلام.
برمودا کد جالبی بود. رم رو آزاد میکنه. ولی به ازای هر فرمی که باز میکنیم حدود یکی دو مگ رم اشغال میمونه. یعنی مثلا 10 بار فرم رو باز کنیم و بعد همه رو ببندیم رم آزاد میشه ولی حدود 20 مگ اشغال میمونه.
سلام.
برمودا شما آرایه رو تو کلاس تعریف کردی. اگه من بخوام تو خود فرمم تعریف کنم این روش جواب نمیده.
کسی روش دیگه ای به ذهنش نمیرسه؟
چه اجباری هست که تو فرم تعریف بشه؟!!!
در ضمن با این کد اگه تو فرم هم تعریف بشه جواب میده :
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();
}
}
از چه طریقی چک می کنید که مقدار RAM اشغالی چه مقدار هست؟نقل قول:
ولی به ازای هر فرمی که باز میکنیم حدود یکی دو مگ رم اشغال میمونه. یعنی مثلا 10 بار فرم رو باز کنیم و بعد همه رو ببندیم رم آزاد میشه ولی حدود 20 مگ اشغال میمونه.
اگه از Task Manager ویندوز استفاده می کنید، عددی که بهتون نشون میده چندان قابل اطمینان نیست، چون وقتی برنامه حافظه ایی را آزاد میکنه، به سرعت اون حافظه به ویندوز برگشت داده نمیشه، بلکه بصورت Allocated برای اون Process باقی می مونه تا زمانی که یا خود Process ازش استفاده کنه، یا ویندوز اونو نیاز داشته باشه. برای بررسی وضعیت مصرف حافظه برنامه از ابزارهایی که برای این کار تولید شدند استفاده کنید.
سلام.
برمودا جان من که فقط نمیخوام یه آرایه تعریف کنم که تو کلاس تعریف کنم یا تو form closing بیام مقدارش رو 0 کنم. کلی متغیر هست و همشون هم تو فرمم هستن و با اشیا فرم ارتباط دارن. میشه برد تو کلاس ولی من میخوام بدونم وقتی داخل فرم هستن و فرم بسته میشه چطور میشه رم رو آزاد کرد. آرایه رو فقط برای تست مثال زدم.
جناب کشاورز من هم همینو میگم. میگم رم آزاد نمیشه و من میخوام با کد نویسی بلافاصله آزادش کنم.
سار جان از زحمات شما هم ممنونم.
دوست عزیز باید بنابه اون کاری که میخواین انجام بدین یه روشی پیدا کنین که بشه باهاش Memory رو آزاد کرد (البته PageFile بگم بهتره )
ولی بر اساس ساختار کلاس ها اگه شما این کارو با طراحی کلاس ها انجام بدین بهتر نتیجه خواهید گرفت
(در کل 90% یه روش مطلق واسه این کاری که شما میگین وجود نداره )
اگر نظر من موردی داشت خوشحال میشم اطلاعات کامل تری بگیرم از دوستان
سلام.
راستش برنامه من کلاینت سروریه.
تو این تاپیک مشکلمو مطرح کردم ولی جواب نگرفتم.
https://barnamenevis.org/showthread.php?t=88885
خلاصه مشکلم اینه که وقتی ارتباط برقرار میشه و بعد که دیسکانکت کنم دیگه نمیتونم همون پورت رو باز کنم. برمودا فکر کنم این سوال رو تو یاهو هم ازت پرسیده بودم.
خیلی هم سرچ کردم ولی کدی برای حل مشکلم پیدا نکردم.
آخرش طبق معمول که به بن بست میخوریم به فکر کلک رشتی افتادم. گفتم خوب اگه فرم رو ببندم و دوباره باز کنم 100% متغیری که قبلا ساخته شده از بین میره و میشه پورت رو دوباره باز کرد. ولی به یه مشکل جدید بر خوردم و دیدم رم متغیرم رو نگه میداره و باز همون ارور صادر میشه.
حالا شما بگید چی کار کنم.