PDA

View Full Version : مقاله: راهکاری جالب جهت برطرف کردن مشکل مدیریت حافظه در برنامه های تحت Net Framework.



محمد باقری نسب
شنبه 21 خرداد 1390, 10:58 صبح
به نام خدا

شاید بحثی که در این مقاله قرار است به آن بپردازیم یکی از مهمترین مسائل اصولی و پایه برای برنامه نویسان دات نت می باشد. چرا که مدیریت حافظه یکی از مشکلاتی است که همه برنامه نویسان دات نت با آن برخورد داشته و یا در آینده خواهند داشت!

چرا در دات نت نمی توان حافظه را به طور کامل آزاد کرد؟
نکته اینجاست که سیستم نظارت بر حافظه در دات نت مدیریت شده است (Managed) برای همین به برنامه نویس اجازه داده نمی شود که خود در مورد مدیریت کردن حافظه تصمیم بگیرد.

مشکل سیستم مدیریت حافظه در دات نت چیست؟
سیستم مدیریت کننده حافظه در دات نت ممکن است در مواقعی بتواند حافظه ای که برنامه اشغال کرده است را آزاد سازی کند ولی در اکثر مواقع این کار به درستی انجام نمی شود. در هر حال هرچند شرکت مایکروسافت کلاسی به نام GC را تعبیه کرده است (Garbage Collector) که به صورت اتوماتیک اشیاء ای که نیازی به وجود آنها نیست را از حافظه پاک کند ، ولی متاسفانه این کلاس نیز گاهی درست عمل نمی کند.

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

راهکار آزاد سازی کامل حافظه در دات نت

جهت خواندن ادامه مقاله و دریافت فایلهای مربوطه به آدرس زیر مراجعه نمایید:

ادامه مقاله... (http://mbnsoft.ir/index.php/article/net-framework/11-article/net-framework/20-article2.html)

http://mbnsoft.ir/index.php/article/net-framework/11-article/net-framework/20-article2.html

haghft
شنبه 21 خرداد 1390, 14:40 عصر
مطلب مفیدی بود ممنون ولی من این مطلب اینجوری دیدم میتونید دربارش توضیح بدید:
internal static void ReduceMemory()
{
try {
Process loProcess = Process.GetCurrentProcess();
loProcess.MaxWorkingSet = (IntPtr)((int)loProcess.MaxWorkingSet);
loProcess.MinWorkingSet = (IntPtr)((int)loProcess.MinWorkingSet);
} catch (Exception e) {
Debug.WriteLine(e);
}
}

saman6384
شنبه 21 خرداد 1390, 14:59 عصر
برا منم جالبه بدونم 300000 از کجا بدس اومده!؟؟

محمد باقری نسب
شنبه 21 خرداد 1390, 15:05 عصر
طی تست های بسیاری که انجام شد واکنش کد به این عدد نسبت به اعداد بالاتر و یا پایینتر نتیجه بسیار پایدارتر و دقیقتری بر روی مقدار حافظه تخصیص داده شده برای برنامه دارد! در اصل این عدد نتیجه ی یک تست و خطای چند هفته ای می باشد. در محدوده این عدد throw شدن exception جهت انجام فرآیند آزاد سازی حافظه به حداقل می رسد. (این اتفاق زمانی رخ میدهد که بخواهید به کرات از این کد استفاده کنید. مثلا فراخوانی کد بوسیله تایمر)

exlord
شنبه 21 خرداد 1390, 15:37 عصر
البته لازم می دانم که نکته ای را هم در رابطه با این مقاله ذکر کنم و آن هم اینکه:
حل مشکلاتی از این دست که جنبه عمومی داشته و همه برنامه نویسان را مدتی است درگیر کرده کاری بس بزرگ و وقت گیر می باشد ، حتی اگر یک خط کد هم نتیجه اش باشد. چرا که کشف همان یک خط کد شگفت انگیز جهت رفع مشکلی به این بزرگی خود کاری بس عظیم می باشد. پس از دوستان برنامه نویس خواهشمندم که کارهایی از این دست را بزرگ بشمارند تا مبادا نویسنده مقاله نیز پس از فاش کردن این راهکار پشیمان شود و در آینده نیز اگر راهکاری برای رفع مشکلی پیدا شد از ارائه آن خودداری کند!

من پیشاپیش عذر میخوام ازتون و از زحماتتون هم قدردانی میکنم .... ولی :
You are not really fixing anything when you reduce the working set. You are just forcing memory pages resident in RAM to get paged out to the OS paging file. As your program continues executing, those pages will eventually get swapped back in, now slowing down your program due to the required hard disk access. The Windows memory manager is quite capable of taking care of that herself. And she'll pick pages that haven't been used for a while rather than the pages of your running program. The only time it would be appropriate the trim the working set is when you know your program is going to be idle for a while.

اگه نیاز به ترجمه باشه بفرمایین ...

محمد باقری نسب
شنبه 21 خرداد 1390, 15:59 عصر
شما لطف کنید منبع مطلبی رو که گذاشتین ذکر کنید که احتمالا از توی یه فروم دیگه مطلب رو دقیقا کپی کردید که البته اطلاعات ناقصیه!

واسه اینکه این کد بر روی انواع سیستمهای مختلف با مشخصات سخت افزاری پایین به طور چشمگیری پاسخگو بوده. جهت اطمینان هم نمیخواد زیاد به خودتون فشار بیارید ، می تونید خودتون با یه پروژه WPF که معمولا حافضه بالاتری به طور استاندارد نسبت به انواع پروژه های دات نت اشغال میکنه و روی سیستم های با حافظه بالا هم به زور کار میکنه ، یه امتحانی بکنید. ضرر نداره!

haghft
شنبه 21 خرداد 1390, 17:47 عصر
ولی به نظر میاد تعیین این عدد مشکل ایجاد کنه یه جورایی مشکوک میزنه البته من تو اینترنت گشتم کسای دیگری هم از روش استفاده کردند مثل نرم افزار media portal که سورسشم اینجاست:
https://sources.team-mediaportal.com/svn/public/trunk/mediaportal/MPTray/Program.cs
که البته روشش با روش این دوستمون یکم فرق داره که بنظرم این روش درستر باشه چون برنامه رو کمتر محدود به یه عدد میکنه و یه بازه تعیین میکنه البته اینو حدس میزنما شاید اشتباه باشه دوستان تصحیح کنن روشش اینه:
// reduce the memory footprint of the app
Process process = Process.GetCurrentProcess();
process.MaxWorkingSet = (IntPtr)900000;
process.MinWorkingSet = (IntPtr)300000;

barbodsoft.com
شنبه 21 خرداد 1390, 19:23 عصر
سلام دوستان
بحث جالبی هست. ولی مهن نتونستم کدتون رو به vb تبدیل کنم. از کانورتو ها هم استفاده کردم ولی نتیجه اشتباه می ده .

می شه کدبالا رو برایvb. هم بزارید

Felony
یک شنبه 22 خرداد 1390, 06:18 صبح
شما لطف کنید منبع مطلبی رو که گذاشتین ذکر کنید که احتمالا از توی یه فروم دیگه مطلب رو دقیقا کپی کردید که البته اطلاعات ناقصیه!

The working set is granular by the size of a memory page. 4096 bytes in Windows x86. The casts are necessary because memory size is expressed in 8 bytes on 64-bit Windows but 4 bytes on 32-bit windows. This code could technically only work on 32-bit Windows.

You are not really fixing anything when you reduce the working set. You are just forcing memory pages resident in RAM to get paged out to the OS paging file. As your program continues executing, those pages will eventually get swapped back in, now slowing down your program due to the required hard disk access. The Windows memory manager is quite capable of taking care of that herself. And she'll pick pages that haven't been used for a while rather than the pages of your running program. The only time it would be appropriate the trim the working set is when you know your program is going to be idle for a while.

nobugz , Microsoft MVP, Moderator

منبع : http://social.msdn.microsoft.com/forums/en-US/clr/thread/442bd555-f9b5-41b5-a97f-3fcbdae7fd69/

محمد باقری نسب
یک شنبه 22 خرداد 1390, 08:19 صبح
سلام دوستان
بحث جالبی هست. ولی مهن نتونستم کدتون رو به vb تبدیل کنم. از کانورتو ها هم استفاده کردم ولی نتیجه اشتباه می ده .

می شه کدبالا رو برایvb. هم بزارید

دوست من زیاد فرقی نمیکنه:

Public Sub FlushMemory()
Dim prs As System.Diagnostics.Process = System.Diagnostics.Process.GetCurrentProcess()
Try
prs.MinWorkingSet = 300000
Catch
End Try
End Sub

mehrvarz9
پنج شنبه 26 خرداد 1390, 01:21 صبح
با سلام

راستش من از این کد و اینکه دقیقا چه کاری انجام می ده چیزی نفهمیدم و نمی دونم که آیا واقعا کارا هست یا نه.

ولی درصد Physical Memory در عکس هاتون عجیب نیست؟!!!

محمد باقری نسب
شنبه 28 خرداد 1390, 08:47 صبح
عزیزم مشکلی نیست میتونید خودتون بوسیله ی یه دونه windows application ساده تستش کنید!

lastgoldentiger
دوشنبه 27 شهریور 1391, 06:50 صبح
به عنوان کسی که در بالاترین سطح ممکن ، درگیر این مشکل بوده نمی تونم معجزه این کد رو باور کنم
امید وارم تا آخر عمر هیچ مساله لاینحلی براتون پیش نیاد.
بسیار بسیار سپاس:لبخندساده: