andrew4582

PhysicalMemoryMonitor

Jun 12th, 2012
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.59 KB | None | 0 0
  1. using System;
  2. using System.Runtime.ConstrainedExecution;
  3. using System.Runtime.InteropServices;
  4. using System.Security;
  5. using System.Text;
  6.  
  7. namespace Core.Diagnostics {
  8.  
  9.     internal sealed class PhysicalMemoryMonitor:MemoryMonitor {
  10.         private const int MIN_TOTAL_MEMORY_TRIM_PERCENT = 10;
  11.         private static readonly long TARGET_TOTAL_MEMORY_TRIM_INTERVAL_TICKS = 0xb2d05e00L;
  12.  
  13.         private PhysicalMemoryMonitor() {
  14.         }
  15.  
  16.         internal PhysicalMemoryMonitor(int physicalMemoryLimitPercentage) {
  17.             long totalPhysical = MemoryMonitor.TotalPhysical;
  18.             if(totalPhysical >= 0x100000000L) {
  19.                 base._pressureHigh = 0x63;
  20.             }
  21.             else if(totalPhysical >= 0x80000000L) {
  22.                 base._pressureHigh = 0x62;
  23.             }
  24.             else if(totalPhysical >= 0x40000000L) {
  25.                 base._pressureHigh = 0x61;
  26.             }
  27.             else if(totalPhysical >= 0x30000000L) {
  28.                 base._pressureHigh = 0x60;
  29.             }
  30.             else {
  31.                 base._pressureHigh = 0x5f;
  32.             }
  33.             base._pressureLow = base._pressureHigh - 9;
  34.             this.SetLimit(physicalMemoryLimitPercentage);
  35.             base.InitHistory();
  36.         }
  37.  
  38.         [SecuritySafeCritical]
  39.         protected override int GetCurrentPressure() {
  40.             MEMORYSTATUSEX memoryStatusEx = new MEMORYSTATUSEX();
  41.             memoryStatusEx.Init();
  42.             if(UnsafeNativeMethods.GlobalMemoryStatusEx(ref memoryStatusEx) == 0) {
  43.                 return 0;
  44.             }
  45.             return memoryStatusEx.dwMemoryLoad;
  46.         }
  47.  
  48.         internal override int GetPercentToTrim(DateTime lastTrimTime,int lastTrimPercent) {
  49.             int num = 0;
  50.             if(base.IsAboveHighPressure()) {
  51.                 long ticks = DateTime.UtcNow.Subtract(lastTrimTime).Ticks;
  52.                 if(ticks > 0L) {
  53.                     num = Math.Min(50,(int)((lastTrimPercent * TARGET_TOTAL_MEMORY_TRIM_INTERVAL_TICKS) / ticks));
  54.                     num = Math.Max(10,num);
  55.                 }
  56.             }
  57.             return num;
  58.         }
  59.  
  60.         internal void SetLimit(int physicalMemoryLimitPercentage) {
  61.             if(physicalMemoryLimitPercentage != 0) {
  62.                 base._pressureHigh = Math.Max(3,physicalMemoryLimitPercentage);
  63.                 base._pressureLow = Math.Max(1,base._pressureHigh - 9);
  64.             }
  65.         }
  66.  
  67.         internal long MemoryLimit {
  68.             get {
  69.                 return (long)base._pressureHigh;
  70.             }
  71.         }
  72.     }
  73.  
  74.     internal abstract class MemoryMonitor {
  75.         protected int _i0;
  76.         protected int _pressureHigh;
  77.         protected int[] _pressureHist;
  78.         protected int _pressureLow;
  79.         protected int _pressureTotal;
  80.         protected const long GIGABYTE = 0x40000000L;
  81.         protected const int GIGABYTE_SHIFT = 30;
  82.         protected const int HISTORY_COUNT = 6;
  83.         protected const long KILOBYTE = 0x400L;
  84.         protected const int KILOBYTE_SHIFT = 10;
  85.         protected const long MEGABYTE = 0x100000L;
  86.         protected const int MEGABYTE_SHIFT = 20;
  87.         private static long s_totalPhysical;
  88.         private static long s_totalVirtual;
  89.         protected const long TERABYTE = 0x10000000000L;
  90.         protected const int TERABYTE_SHIFT = 40;
  91.  
  92.         [SecuritySafeCritical]
  93.         static MemoryMonitor() {
  94.             MEMORYSTATUSEX memoryStatusEx = new MEMORYSTATUSEX();
  95.             memoryStatusEx.Init();
  96.             if(UnsafeNativeMethods.GlobalMemoryStatusEx(ref memoryStatusEx) != 0) {
  97.                 s_totalPhysical = memoryStatusEx.ullTotalPhys;
  98.                 s_totalVirtual = memoryStatusEx.ullTotalVirtual;
  99.             }
  100.         }
  101.  
  102.         protected MemoryMonitor() {
  103.         }
  104.  
  105.         protected abstract int GetCurrentPressure();
  106.         internal abstract int GetPercentToTrim(DateTime lastTrimTime,int lastTrimPercent);
  107.         protected void InitHistory() {
  108.             int currentPressure = this.GetCurrentPressure();
  109.             this._pressureHist = new int[6];
  110.             for(int i = 0;i < 6;i++) {
  111.                 this._pressureHist[i] = currentPressure;
  112.                 this._pressureTotal += currentPressure;
  113.             }
  114.         }
  115.  
  116.         internal bool IsAboveHighPressure() {
  117.             return (this.PressureLast >= this.PressureHigh);
  118.         }
  119.  
  120.         internal void Update() {
  121.             int currentPressure = this.GetCurrentPressure();
  122.             this._i0 = (this._i0 + 1) % 6;
  123.             this._pressureTotal -= this._pressureHist[this._i0];
  124.             this._pressureTotal += currentPressure;
  125.             this._pressureHist[this._i0] = currentPressure;
  126.         }
  127.  
  128.         internal int PressureHigh {
  129.             get {
  130.                 return this._pressureHigh;
  131.             }
  132.         }
  133.  
  134.         internal int PressureLast {
  135.             get {
  136.                 return this._pressureHist[this._i0];
  137.             }
  138.         }
  139.  
  140.         internal int PressureLow {
  141.             get {
  142.                 return this._pressureLow;
  143.             }
  144.         }
  145.  
  146.         internal static long TotalPhysical {
  147.             get {
  148.                 return s_totalPhysical;
  149.             }
  150.         }
  151.  
  152.         internal static long TotalVirtual {
  153.             get {
  154.                 return s_totalVirtual;
  155.             }
  156.         }
  157.     }
  158.  
  159.     [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Unicode)]
  160.     internal struct MEMORYSTATUSEX {
  161.         internal int dwLength;
  162.         internal int dwMemoryLoad;
  163.         internal long ullTotalPhys;
  164.         internal long ullAvailPhys;
  165.         internal long ullTotalPageFile;
  166.         internal long ullAvailPageFile;
  167.         internal long ullTotalVirtual;
  168.         internal long ullAvailVirtual;
  169.         internal long ullAvailExtendedVirtual;
  170.         internal void Init() {
  171.             this.dwLength = Marshal.SizeOf(typeof(MEMORYSTATUSEX));
  172.         }
  173.     }
  174.  
  175.     [SuppressUnmanagedCodeSecurity,SecurityCritical]
  176.     internal static class UnsafeNativeMethods {
  177.         private const string ADVAPI32 = "ADVAPI32.DLL";
  178.         private const string KERNEL32 = "KERNEL32.DLL";
  179.  
  180.         [DllImport("KERNEL32.DLL",CharSet = CharSet.Unicode)]
  181.         internal static extern int GetModuleFileName(IntPtr module,StringBuilder filename,int size);
  182.         [DllImport("KERNEL32.DLL",CharSet = CharSet.Unicode)]
  183.         internal static extern int GlobalMemoryStatusEx(ref MEMORYSTATUSEX memoryStatusEx);
  184.         [ReliabilityContract(Consistency.WillNotCorruptState,Cer.Success),DllImport("ADVAPI32.DLL")]
  185.         internal static extern int RegCloseKey(IntPtr hKey);
  186.     }
  187. }
Advertisement
Add Comment
Please, Sign In to add comment