c# - niif - formacion profesional del contador publico
TamaƱo de la memoria de proceso: diferentes contadores (6)
Estoy tratando de averiguar cuánta memoria está usando mi propio proceso .Net server (para fines de monitoreo y registro).
Estoy usando:
Process.GetCurrentProcess().PrivateMemorySize64
Sin embargo, el objeto Process tiene varias propiedades diferentes que me permiten leer el espacio de memoria utilizado: Paged, NonPaged, PagedSystem, NonPagedSystem, Private, Virtual, WorkingSet
y luego los "picos": que supongo que almacenan los valores máximos que estos últimos tomaron.
Leer a través de la definición de MSDN de cada propiedad no me resultó demasiado útil. 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.
Entonces mi pregunta es, obviamente, "¿cuál debo usar?", Y sé que la respuesta es "depende".
Este proceso básicamente contendrá un montón de listas en memoria de cosas que están sucediendo, mientras que otros procesos se comunican con él y lo consultan por cosas. 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é?
El conjunto de trabajo no es una buena propiedad para usar. 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.
OK, encontré a través de Google la misma página que mencionó Lars, y creo que es una gran explicación para las personas que no saben cómo funciona la memoria (como yo).
http://shsc.info/WindowsMemoryManagement
Mi breve conclusión fue:
Bytes privados = La memoria que mi proceso ha solicitado para almacenar datos. Algunos de ellos pueden ser paginados en el disco o no. Esta es la información que estaba buscando.
Bytes virtuales = Bytes privados, más el espacio compartido con otros procesos para archivos DLL cargados, etc.
Working Set = La porción 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!
Sugiero que también controle la frecuencia con la que ocurren 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.
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 "Bytes privados de WS", 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);
}
Para obtener el valor que da el Administrador de tareas, estoy en desacuerdo con 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 la memoria'' (Administrador de tareas, como se indica) de forma 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 Windows:
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();
}`
Si quiere saber cuánto usa GC, intente:
GC.GetTotalMemory(true)
Si desea saber qué usa su proceso desde Windows (columna Tamaño de VM en TaskManager) intente:
Process.GetCurrentProcess().PrivateMemorySize64
Si desea saber lo que su proceso tiene en la memoria RAM (a diferencia de en el archivo de paginación) (columna Uso de Mem en TaskManager) intente:
Process.GetCurrentProcess().WorkingSet64
Vea aquí para más explicación sobre los diferentes tipos de memoria.