اگر به میزان مصرف حافظه اولیهی برنامههای دات نت دقت کنیم، نسبت به مثلا یک برنامهی MFC چند برابر به نظر میرسند و ... این علت دارد:
زمانیکه یک برنامهی مبتنی بر دات نت اجرا میشود، ابتدا JIT compiler شروع به کار کرده و شروع به کامپایل برنامه میکند. این بارگزاری هم در همان پروسهی اصلی برنامه انجام میشود. به همین جهت میزان مصرف حافظهی برنامههای دات نت عموما بالا به نظر میرسد.
اکنون سؤال اینجا است که آیا می توان این حافظهای را که دیگر مورد استفاده نیست (و توسط JIT compiler اخذ شده) به سیستم بازگرداند و محاسبهی مجددی را در این مورد انجام داد. پاسخ به این سؤال را در متد ReEvaluateWorkingSet زیر میتوان مشاهده کرد:
using System;
using System.Diagnostics;
namespace Toolkit
{
public static class Memory
{
public static void ReEvaluateWorkingSet()
{
try
{
Process loProcess = Process.GetCurrentProcess();
//it doesn't matter what you set maxWorkingSet to
//setting it to any value apparently causes the working set to be re-evaluated and excess discarded
loProcess.MaxWorkingSet = (IntPtr)((int)loProcess.MaxWorkingSet + 1);
}
catch
{
//The above code requires Admin privileges.
//So it's important to trap exceptions in case you're running without admin rights.
}
}
}
}
در این متد ابتدا پروسه جاری دریافت شده و سپس MaxWorkingSet به یک عدد دلخواه تنظیم میشود. مهم نیست که این عدد چه چیزی باشد، زیرا این تنظیم سبب میشود که در پشت صحنه به شکل حساب شدهای حافظهای که مورد استفاده نیست به سیستم بازگردانده شود و سپس عددی که در task manager نمایش داده میشود، مجددا محاسبه گردد. همچنین باید دقت داشت که این کد تنها با دسترسی مدیریتی قابل اجرا است و به همین دلیل وجود این try/catch ضروری است.
نحوه استفاده از متد ReEvaluateWorkingSet در برنامههای WinForms :فایل Program.cs را یافته و سپس در روال رویداد گردان Idle برنامه، متد ReEvaluateWorkingSet را فراخوانی کنید (مثلا هر زمان که برنامه minimized شد اجرا میشود):
//Program.cs
namespace MemUsage
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
//...
Application.Idle += applicationIdle;
}
static void applicationIdle(object sender, EventArgs e)
{
Memory.ReEvaluateWorkingSet();
}
}
}
نحوه استفاده از متد ReEvaluateWorkingSet در برنامههای WPF :فایل App.xaml.cs را یافته و سپس در روال رویدادگردان Deactivated برنامه، متد ReEvaluateWorkingSet را فراخوانی کنید:
//App.xaml.cs
public App()
{
this.Deactivated += appDeactivated;
}
void appDeactivated(object sender, EventArgs e)
{
Memory.ReEvaluateWorkingSet();
}
تاثیر آن هم قابل ملاحظه است (حداقل از لحاظ روانی!). تست کنید!