3

En essayant de mettre en œuvre un outil de surveillance des performances, je veux surveiller des choses de base telles que la mémoire et le processeur.Quelle est la manière la plus efficace d'interroger les compteurs de performance de processus?

Je tente de le faire en utilisant des compteurs de performance que je crois que c'est la « bonne » façon d'interroger les performances des processus en C#, c'est un code d'exemple:

class Program 
    { 
     static void Main(string[] args) 
     { 
      while (true) 
      { 
       var pcs = Process.GetProcesses() 
        .Select(p => new PerformanceCounter("Process", "Working Set - Private", p.ProcessName)); 

       var sw = Stopwatch.StartNew(); 

       foreach (var pc in pcs) 
        pc.NextValue(); 

       Console.WriteLine($"Time taken to read {pcs.Count()} performance counters: {sw.ElapsedMilliseconds}ms"); 

       Thread.Sleep(1000); 
      } 
     } 
    } 

enter image description here

Alors évidemment ~ 12,5 millisecondes pour interroger un processus sur mon système est inacceptable lente. Comment est-ce censé être fait?

je l'ai déjà posé une question connexe à ce poste: Performance Counter read access very slow - How does Task Manager do it?

Mais je me rends compte que je n'étais pas assez précis dans ce poste et a demandé au mauvais qestion. Qu'est-ce que je veux vraiment savoir si je peux faire ce que je veux faire avec les compteurs de performance ou est-ce simplement impossible?

EDIT1:

Je suis sous Windows 10 Pro 1607 - Créer 14393,479

+0

Vous pouvez toujours [utiliser l'API Win32 brute] (http://mjs5.com/2016/06/05/c-get-basic-memory-information-using-getperformanceinfo-api/) ou exécuter un quelques tâches en parallèle. – stuartd

+1

Incidemment, la [page MSDN de performance de la mémoire] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa965225 (v = vs.85) .aspx) indique _ "informations sur la performance de la mémoire est disponible du gestionnaire de mémoire via les compteurs de performance système et via des fonctions telles que GetPerformanceInfo, GetProcessMemoryInfo et GlobalMemoryStatusEx Des applications telles que le Gestionnaire des tâches Windows, le moniteur de fiabilité et de performances et l'outil Explorateur de processus utilisent des compteurs de performance pour afficher les informations de mémoire. et pour les processus individuels. "_ – stuartd

+0

@stuartd vous savez quoi, j'ai complètement oublié le filetage. Je pourrais en effet les faire tourner en parallèle! Je me demande quel impact sur la performance cela aurait .. – mikeysee

Répondre

10

Windows est un peu notoire d'être lent à chaque fois que vous faites quelque chose avec tous les processus en cours d'exécution sur une machine. Mais c'est excessif. Il y a quelque chose de pourri dans l'état de PerformanceCounter, j'ai eu le premier indice de this question. Quelque chose que vous pouvez facilement visualiser dans votre propre programme de test en modifiant le Console.WriteLine() appel:

Console.Write($"Time taken to read {pcs.Count()} performance counters:"); 
    Console.WriteLine($"{sw.ElapsedMilliseconds}ms, {GC.CollectionCount(2)} collections"); 

Sortie sur ma machine:

Time taken to read 124 performance counters: 1633ms, 15 collections 
Time taken to read 124 performance counters: 923ms, 30 collections 
Time taken to read 124 performance counters: 928ms, 45 collections 
Time taken to read 124 performance counters: 934ms, 59 collections 
Time taken to read 124 performance counters: 922ms, 74 collections 
Time taken to read 124 performance counters: 925ms, 89 collections 
...etc 

Ou en d'autres termes, une collection complète des ordures pour chaque ~ 8 appels à PerformanceCounter.NextValue(). Aie. Oui, ça va beaucoup ralentir votre programme.

C'est un comportement remarquablement étrange, pour le moins. Je ne trouve pas de bons indices dans la classe PerformanceCounter elle-même, le code semble très innocent. Il y a un gros morceau de code non géré sous le capot qui est difficile à voir (C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ PerfCounter.dll) mais en regardant ses dépendances ne fournissent pas de preuve convaincante qu'il est responsable. Cela se produit à la fois sur les versions d'exécution v2.0.50727 et v4.0.30319, donc un hack malheureux dans V4.x ne l'explique pas facilement. Ce n'est pas un bon multiple de 8 donc un simple compteur qui oblige les finaliseurs à s'exécuter ne l'explique pas facilement. Ce n'est pas le compteur de performance natif, l'interroger avec WMI ne déclenche aucune collection. Il n'est pas spécifique aux compteurs de mémoire, demandant, disons, "Thread Count" le fait aussi. Pourrait avoir quelque chose à voir avec la version Windows, le mien est Win10 version 1607 (ne peut pas facilement tester un autre).

Microsoft doit s'impliquer dans ce processus. L'auteur de la question que j'ai liée semble avoir créé un bug feedback report for it, j'ai ajouté ce Q + A comme preuve à l'appui. Gardez un oeil sur le rapport de rétroaction, votez pour cela, j'espère qu'ils vont commencer à prêter attention. Ou contactez le support technique Microsoft directement si vous ne voulez pas attendre.


En attendant, vous pouvez obtenir l'espace de noms System.Management.L'utilitaire de code WMI Creator est très pratique pour générer automatiquement le code:

... 
using System.Management;  // Project > Add Reference required 

    public static void QueryWorkingset() { 
     ManagementObjectSearcher searcher = 
      new ManagementObjectSearcher("root\\CIMV2", 
       "SELECT Name, WorkingSetPrivate FROM Win32_PerfRawData_PerfProc_Process"); 
     foreach (ManagementObject queryObj in searcher.Get()) { 
      Console.WriteLine("{0}: {1}", queryObj["Name"], queryObj["WorkingSetPrivate"]); 
     } 
    } 

Encore aucun démon de vitesse, prend environ 1,0 msec par processus sur ma machine. Mais ne brûle pas 100% core comme le fait PerformanceCounter et pas de collections forcées.

+1

Merci monsieur, cela a été incroyablement utile.Je vais mettre à jour mon post original avec ma version Windows (10) et Ajoutez ma voix à ce rapport de bogue et contactez Microsoft via l'un de mes canaux J'ai marqué cette réponse comme correcte jusqu'à ce que nous ayons une solution officielle. – mikeysee