Krzysztof Radzimski

Pasja tworzenia

Ile pamięci zużywa mój program?

07 lipiec
Opublikował Krzysztof Radzimski 7. lipca 2010 10:12

Nie czuję się w żadnym razie ekspertem od zarządzania pamiecią w aplikacjach .NET, ale poniższy kod pomógł mi funkcjonowaniu jednej z moich aplikacji. Co prawda poniższy kod nie pokazuje dokładnie tej wartości, która jest pokazywana w Task Manager, ale jest bliska prawdy. Tak przynajmniej wynika z moich empirycznych doświadczeń.

   1:  string GetMemoryUsage() {
   2:      try {
   3:          Application.DoEvents();
   4:          Process p = Process.GetCurrentProcess();
   5:          if (p != null) {
   6:              return FormatBytes(p.WorkingSet64);
   7:          }
   8:      }
   9:      catch { }
  10:      
  11:      return String.Empty;
  12:   
  13:  }


   1:  [System.Diagnostics.DebuggerStepThrough()]
   2:  string FormatBytes(long bytes) {
   3:      const int scale = 1024;
   4:      string[] orders = new string[] { "GB", "MB", "KB", "b" };
   5:      long max = (long)Math.Pow(scale, orders.Length - 1);
   6:   
   7:      foreach (string order in orders) {
   8:          if (bytes > max)
   9:          {    
  10:             return string.Format("{0:##.##} {1}", 
  11:              decimal.Divide(bytes, max), order);
  12:          }
  13:          max /= scale;
  14:      }
  15:      return "0 b";
  16:  }

 

W ceu odzyskania części pamięci korzystam z funkcji SetProcessWorkingSetSize z Kernel32.dll

   1:  [DllImport("KERNEL32.DLL", 
   2:    EntryPoint="SetProcessWorkingSetSize", 
   3:    SetLastError=true, 
   4:    CallingConvention=CallingConvention.StdCall)]
   5:  internal static extern bool SetProcessWorkingSetSize(
   6:    IntPtr pProcess, 
   7:    int dwMinimumWorkingSetSize, 
   8:    int dwMaximumWorkingSetSize);
   9:   
  10:  internal void ClearMemory() {
  11:      Application.DoEvents();
  12:      try {
  13:          System.Diagnostics.Process p = 
  14:            System.Diagnostics.Process.GetCurrentProcess();
  15:          if (p != null) {
  16:              IntPtr pHandle = p.Handle;
  17:              if (pHandle != IntPtr.Zero) {
  18:          SetProcessWorkingSetSize(pHandle, -1, -1);
  19:              }
  20:          }
  21:      }
  22:      catch { }
  23:   
  24:      GC.Collect();
  25:      GC.WaitForPendingFinalizers();
  26:  }

Tagi: , | Kategorie:

Wyślij link na adres e-mail | Link do tego postu | RSSRSS comment feed