2010-04-09 7 views
7

¿Cómo puedo calcular el conjunto de trabajo privado de la memoria usando C#? Estoy interesado en producir aproximadamente la misma cifra que taskmgr.exe.Cómo calcular el conjunto de trabajo privado (memoria)?

Estoy usando el espacio de nombres Proceso y usando métodos/datos como WorkingSet64 y PrivateMemorySize64, pero estas cifras están desactivadas en 100 MB o más a veces.

Respuesta

23

Este es un número muy variable, no se puede calcular. El administrador de memoria de Windows constantemente intercambia páginas dentro y fuera de la RAM. TaskMgr.exe lo obtiene de un contador de rendimiento. Usted puede obtener el mismo número de esta manera:

using System; 
using System.Diagnostics; 

class Program { 
    static void Main(string[] args) { 
     string prcName = Process.GetCurrentProcess().ProcessName; 
     var counter = new PerformanceCounter("Process", "Working Set - Private", prcName); 
     Console.WriteLine("{0}K", counter.RawValue/1024); 
     Console.ReadLine(); 
    } 
} 

No Tenga en cuenta que el número realmente no significa mucho, caerá cuando empezar otros procesos y competir por la RAM.

+0

¿Qué quiere decir con "el número realmente no significa mucho"? ¿No representa esta cifra la cantidad de memoria que utiliza el proceso que no se puede compartir con otro proceso? Estoy interesado en crear un servicio que mate los procesos "abusivos" del proceso - se define "abusivo" como procesos que usan más de x muchos MB de memoria. Odiaría escribir el servicio si la cifra que estoy usando realmente no significa mucho. ¿Qué sugeriría? – sholsapp

+0

No, eso no es lo que significa el número. Está buscando "Bytes privados", la cantidad de memoria * virtual * tomada por un proceso que otros procesos no pueden compartir. –

+7

Si bien todo lo que se dice es correcto, quería agregar que solo usar 'ProcessName' para buscar la instancia del contador correspondiente no es suficiente. Si tiene múltiples procesos con el mismo (por ejemplo, svchost.exe), los nombres del contador serán "svchost # 1", "svchost # 2", etc. Deberá coincidir a través del contador "ID Process", que también es parte de la categoría de proceso, y 'Process.ID'. –

0

Para usuarios futuros, esto es lo que tuve que hacer para asegurarme de obtener el Conjunto de trabajo privado para procesos que pueden tener varias instancias. Llamo al CurrentMemoryUsage, que obtiene el nombre de proceso correspondiente de GetNameToUseForMemory. Encontré que este ciclo era lento, incluso al filtrar los resultados donde podía. Entonces, es por eso que ves GetNameToUseForMemory usando un diccionario para guardar el nombre en caché.

private static long CurrentMemoryUsage(Process proc) 
{ 
    long currentMemoryUsage; 
    var nameToUseForMemory = GetNameToUseForMemory(proc); 
    using (var procPerfCounter = new PerformanceCounter("Process", "Working Set - Private", nameToUseForMemory)) 
    { 
    //KB is standard 
    currentMemoryUsage = procPerfCounter.RawValue/1024; 
    } 
    return currentMemoryUsage; 
} 

private static string GetNameToUseForMemory(Process proc) 
{ 
    if (processId2MemoryProcessName.ContainsKey(proc.Id)) 
    return processId2MemoryProcessName[proc.Id]; 
    var nameToUseForMemory = String.Empty; 
    var category = new PerformanceCounterCategory("Process"); 
    var instanceNames = category.GetInstanceNames().Where(x => x.Contains(proc.ProcessName)); 
    foreach (var instanceName in instanceNames) 
    { 
    using (var performanceCounter = new PerformanceCounter("Process", "ID Process", instanceName, true)) 
    { 
     if (performanceCounter.RawValue != proc.Id) 
     continue; 
     nameToUseForMemory = instanceName; 
     break; 
    } 
    } 
    if(!processId2MemoryProcessName.ContainsKey(proc.Id)) 
    processId2MemoryProcessName.Add(proc.Id, nameToUseForMemory); 
    return nameToUseForMemory; 
} 
+0

Tenga en cuenta que el almacenamiento en memoria caché del valor no funcionará, ya que el proceso "anterior" se puede cerrar y el nombre de instancia obtiene "re-keyed" http://blogs.technet.com/b/askperf/archive/2010/03/30/perfmon -identifying-processes-by-pid-instead-of-instance.aspx – Andre

+0

@Andre ¡tienes razón! tks –

Cuestiones relacionadas