2012-01-23 7 views
7

Zgodnie z How to use .NET PerformanceCounter to track memory and CPU usage per process?PerformanceCounter powinien podać liczbę pamięci wykorzystania danego procesu.Jak poprawnie używać licznika wydajności lub klasy procesów w języku C#, aby uzyskać wykorzystanie pamięci w bieżącym procesie?

Według instancji MSDN, Process może również dać mi mniej więcej taką samą liczbę.

W celu zweryfikowania moich założeń, napisałem poniższy kod:

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); 
    } 

} 

Wyjście wygląda

      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 

Dokładnie to samo! W przeciwieństwie do tego prywatne bajty wyświetlane w Process Explorer wzrosły z 32732 do 63620.

Czy robię coś złego?

Odpowiedz

8

Musisz powiedzieć swojej instancji process, że powinien odświeżyć swoje dane z pamięci podręcznej. Dane nie są gromadzone za każdym razem, gdy uzyskujesz dostęp do nieruchomości w celach związanych z wydajnością. Musisz ręcznie zażądać aktualizacji danych.

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); 
} 

To dla twojego process. Dla liczników wydajności, NextValue() ma za każdym razem pobierać nowe świeże dane, więc nie mogę wyjaśnić, dlaczego nie ma ich na twoim komputerze. Na moim działa dobrze.

EDIT:

Z process.Refresh() dodał, oto co mam:

      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

Czy podane wartości są dokładnie takie same, czy nie? Czy możesz je opublikować? Chcę się przyjrzeć. – Gqqnbig

+0

Zobacz zaktualizowaną odpowiedź. – ken2k

+1

To dziwne, że teraz nawet bez metody odświeżania mój PerformanceCounter może podać prawidłową liczbę .... BTW, odświeżanie działa dobrze. Dzięki. – Gqqnbig

4

Uwaga: moja pamięć profiler (.NET Memory Profiler) ujawniła, że ​​Process.Refresh() przydziela znacząca fragment pamięci tymczasowo, więc miej to na uwadze, jeśli regularnie czytasz liczniki wydajności za pomocą licznika czasu.

Powiązane problemy