2012-01-23 21 views
7

De acuerdo con How to use .NET PerformanceCounter to track memory and CPU usage per process?PerformanceCounter debería darme la cantidad de memoria utilizada en un proceso determinado.¿Cómo usar el contador de rendimiento o la clase de proceso correctamente en C# para obtener el uso de la memoria del proceso actual?

Según MSDN, Process instancia también puede darme más o menos el mismo número.

Con el fin de verificar mis suposiciones, escribí el siguiente código:

class Program 
{ 
    static Process process = Process.GetCurrentProcess(); 

    static PerformanceCounter privateBytesCounter = new PerformanceCounter("Process", "Private Bytes", process.ProcessName); 
    static PerformanceCounter workingSetCounter = new PerformanceCounter("Process", "Working Set", process.ProcessName); 

    static void Main(string[] args) 
    { 


     GetMeasure(); 

     Console.WriteLine("\nPress enter to allocate great amount of memory"); 
     Console.ReadLine(); 
     int[] arr = new int[10000000]; 
     for (int i = 0; i < arr.Length; i++) 
     { 
      arr[i] = i; 
     } 

     GetMeasure(); 

     privateBytesCounter.Dispose(); 
     workingSetCounter.Dispose(); 
     Console.ReadKey(); 
    } 

    private static void GetMeasure() 
    { 
     Console.WriteLine("{0,38} {1,20}", "Private bytes", "working set"); 
     Console.WriteLine("process data{0,23} {1,20}", process.PrivateMemorySize64/1024, process.WorkingSet64/1024); 
     Console.WriteLine("PerformanceCounter data{0,12} {1,20}", privateBytesCounter.NextValue()/1024, workingSetCounter.NextValue()/1024); 
    } 

} 

La salida se ve como

      Private bytes   working set 
process data     22880    17516 
PerformanceCounter data  21608    15608 

Press enter to allocate great amount of memory 

         Private bytes   working set 
process data     22880    17516 
PerformanceCounter data  21608    15608 

exactamente lo mismo! En el contraste, los bytes privados que se muestran en Process Explorer aumentaron de 32732 a 63620.

Entonces, ¿estoy haciendo algo mal?

Respuesta

8

Tiene que indicar a su instancia process que debe actualizar sus datos en caché. Los datos no se recopilan cada vez que accede a una propiedad para fines de rendimiento. Tienes que exigir manualmente la actualización de datos.

private static void GetMeasure() 
{ 
    process.Refresh(); // Updates process information 

    Console.WriteLine("{0,38} {1,20}", "Private bytes", "working set"); 
    Console.WriteLine("process data{0,23} {1,20}", process.PrivateMemorySize64/1024, process.WorkingSet64/1024); 
    Console.WriteLine("PerformanceCounter data{0,12} {1,20}", privateBytesCounter.NextValue()/1024, workingSetCounter.NextValue()/1024); 
} 

Eso es para su process. Para los contadores de rendimiento, se supone que NextValue() recupera una nueva información nueva cada vez, por lo que no puedo explicar por qué no lo hace en su máquina. En el mío funciona bien.

EDITAR:

Con la process.Refresh() añadió, esto es lo que me sale:

      Private bytes   working set 
process data     25596    22932 
PerformanceCounter data  26172    23600 

Press enter to allocate great amount of memory 
         Private bytes   working set 
process data     65704    61848 
PerformanceCounter data  65828    61880 
+0

¿Los valores dados por los dos son exactamente iguales o no? ¿Puedes publicarlos? Quiero echarle un vistazo. – Gqqnbig

+0

Ver respuesta actualizada. – ken2k

+1

Es extraño que ahora, incluso sin el método de actualización, mi PerformanceCounter pueda dar el número correcto ... Por cierto, el método de actualización funciona bien. Gracias. – Gqqnbig

4

Precaución: mi perfilador de memoria (memoria de perfiles .NET) reveló que Process.Refresh() asigna una significativa gran cantidad de memoria de forma temporal, así que tenlo en cuenta si estás leyendo los contadores de rendimiento de forma regular mediante el uso de un temporizador.

Cuestiones relacionadas