2008-08-27 17 views
13

Estoy tratando de averiguar cuánta memoria está usando mi propio proceso .Net server (con fines de monitorización y registro).Tamaño de la memoria de proceso - Diferentes contadores

que estoy usando:

Process.GetCurrentProcess().PrivateMemorySize64 

Sin embargo, el objeto de proceso tiene varias propiedades diferentes que me dejó leer el espacio de memoria utilizado: paginado, bloque no paginado, PagedSystem, NonPagedSystem, privada, virtual, WorkingSet

y luego los "picos": que supongo que almacenan los valores máximos que estos últimos tomaron.

Lectura a través de la definición de MSDN de cada propiedad no ha demostrado ser demasiado útil para mí. Debo admitir que mi conocimiento sobre cómo se gestiona la memoria (en lo que respecta a la paginación y virtualización) es muy limitado.

Así que mi pregunta es, obviamente, "¿cuál debería usar?", Y sé que la respuesta es "depende".

Este proceso básicamente mantener un montón de listas de la memoria de las cosas que están sucediendo, mientras que otros procesos se comunican con él y realizan indagaciones para la materia. Estoy esperando que el servidor donde se ejecutará requiera mucha RAM, por lo que estoy consultando estos datos a lo largo del tiempo para poder estimar los requisitos de RAM en comparación con los tamaños de las listas que guarda dentro.

Entonces ... ¿Cuál debería usar y por qué?

Respuesta

14

Si desea saber cuánto utiliza el GC tratar:

GC.GetTotalMemory(true) 

Si usted quiere saber lo que su proceso utiliza desde Windows (columna Tamaño VM en el administrador de tareas) Proveedores:

Process.GetCurrentProcess().PrivateMemorySize64 

Si usted quiere saber lo que su proceso tiene en la memoria RAM (al contrario que en el archivo de paginación) (columna de Uso de memoria en el administrador de tareas) Proveedores:

Process.GetCurrentProcess().WorkingSet64 

Consulte here para obtener más explicaciones sobre los diferentes tipos de memoria.

0

El conjunto de trabajo no es una buena propiedad para su uso. Según lo que veo, incluye todo lo que el proceso puede tocar, incluso bibliotecas compartidas por varios procesos, por lo que está viendo bytes contados dobles en ese contador. La memoria privada es un contador mucho mejor para mirar.

4

Bueno, he encontrado a través de Google la misma página que Lars mencionado, y yo creo que es una gran explicación para las personas que no saben muy bien cómo funciona la memoria (como yo).

http://shsc.info/WindowsMemoryManagement

Mi breve conclusión fue:

  • Bytes privados = La memoria ha solicitado mi proceso para almacenar datos. Algunos de ellos pueden ser paginados en el disco o no. Esta es la información que estaba buscando.

  • Bytes virtuales = Los Bytes privados, más el espacio compartido con otros procesos para DLL cargadas, etc.

  • Working Set = La parte de TODA la memoria de mi proceso que no ha sido paginada al disco. Por lo tanto, la cantidad paginada en el disco debe ser (Virtual - Working Set).

Gracias a todos por su ayuda!

0

Sugiero que también controle la frecuencia con la que se producen los fallos de página. Un error de página ocurre cuando intenta acceder a algunos datos que se han movido de la memoria física al archivo de intercambio y el sistema tiene que leer la página del disco antes de poder acceder a estos datos.

5

Si desea utilizar la "Memoria (conjunto de trabajo privado)" como se muestra en el administrador de tareas de Windows Vista, que es el equivalente de Process Explorer "WS Bytes privados", aquí está el código. Probablemente sea mejor lanzar este bucle infinito en una tarea de hilo/fondo para obtener estadísticas en tiempo real.

using System.Threading; 
using System.Diagnostics; 

//namespace...class...method 

Process thisProc = Process.GetCurrentProcess(); 
PerformanceCounter PC = new PerformanceCounter(); 

PC.CategoryName = "Process"; 
PC.CounterName = "Working Set - Private"; 
PC.InstanceName = thisProc.ProcessName; 

while (true) 
{ 
String privMemory = (PC.NextValue()/1000).ToString()+"KB (Private Bytes)"; 
//Do something with string privMemory 

Thread.Sleep(1000); 
} 
2

Para obtener el valor que le da el Administrador de tareas, me apetece la solución anterior de Mike Regan. Sin embargo, un cambio: no es: perfCounter.NextValue()/1000; pero perfCounter.NextValue()/1024; (es decir, un kilobyte real). Esto le da el valor exacto que ve en el Administrador de tareas.

A continuación se muestra una solución completa para mostrar el 'uso de memoria' (administrador de tareas, como se muestra) de manera sencilla en su aplicación WPF o WinForms (en este caso, simplemente en el título). Simplemente llame a este método dentro del nuevo constructor de ventana:

private void DisplayMemoryUsageInTitleAsync() 
    { 
     origWindowTitle = this.Title; // set WinForms or WPF Window Title to field 
     BackgroundWorker wrkr = new BackgroundWorker(); 
     wrkr.WorkerReportsProgress = true; 

     wrkr.DoWork += (object sender, DoWorkEventArgs e) => { 
      Process currProcess = Process.GetCurrentProcess(); 
      PerformanceCounter perfCntr = new PerformanceCounter(); 
      perfCntr.CategoryName = "Process"; 
      perfCntr.CounterName = "Working Set - Private"; 
      perfCntr.InstanceName = currProcess.ProcessName; 

      while (true) 
      { 
       int value = (int)perfCntr.NextValue()/1024; 
       string privateMemoryStr = value.ToString("n0") + "KB [Private Bytes]"; 
       wrkr.ReportProgress(0, privateMemoryStr); 
       Thread.Sleep(1000); 
      } 
     }; 

     wrkr.ProgressChanged += (object sender, ProgressChangedEventArgs e) => { 
      string val = e.UserState as string; 
      if (!string.IsNullOrEmpty(val)) 
       this.Title = string.Format(@"{0} ({1})", origWindowTitle, val); 
     }; 

     wrkr.RunWorkerAsync(); 
    }` 
+1

Esta es la más precisa que he encontrado. Quería hacer coincidir lo que mostraba el administrador de tareas. – Andez

Cuestiones relacionadas