Question

J'essaie de savoir combien de mémoire mon propre processus de serveur .Net utilise (à des fins de surveillance et de journalisation).

J'utilise:

Process.GetCurrentProcess().PrivateMemorySize64

Cependant, l'objet Process possède plusieurs propriétés différentes qui me permettent de lire l'espace mémoire utilisé :Paginé, non paginé, PagedSystem, NonPagedSystem, privé, virtuel, WorkingSet

et puis les "pics" :ce qui, je suppose, stocke simplement les valeurs maximales que ces derniers ont jamais prises.

La lecture de la définition MSDN de chaque propriété ne m'a pas été très utile.Je dois admettre que mes connaissances sur la façon dont la mémoire est gérée (en ce qui concerne la pagination et le virtuel) sont très limitées.

Ma question est donc évidemment « laquelle dois-je utiliser ? », et je sais que la réponse est « ça dépend ».

Ce processus conservera essentiellement un tas de listes en mémoire de choses qui se passent, tandis que d'autres processus communiqueront avec lui et lui interrogeront des éléments.Je m'attends à ce que le serveur sur lequel cela s'exécutera nécessite beaucoup de RAM, et j'interroge donc ces données au fil du temps pour pouvoir estimer les besoins en RAM par rapport à la taille des listes qu'il contient.

Donc...Lequel dois-je utiliser et pourquoi ?

Était-ce utile?

La solution

Si vous voulez savoir combien le GC utilise, essayez :

GC.GetTotalMemory(true)

Si vous souhaitez savoir ce que votre processus utilise depuis Windows (colonne Taille de la VM dans TaskManager), essayez :

Process.GetCurrentProcess().PrivateMemorySize64

Si vous voulez savoir ce que votre processus a dans la RAM (par opposition à dans le fichier d'échange) (colonne Utilisation de la mémoire dans TaskManager), essayez :

Process.GetCurrentProcess().WorkingSet64

Voir ici pour plus d'explications sur les différents types de mémoire.

Autres conseils

OK, j'ai trouvé via Google la même page que celle mentionnée par Lars, et je pense que c'est une excellente explication pour les personnes qui ne savent pas vraiment comment fonctionne la mémoire (comme moi).

http://shsc.info/WindowsMemoryManagement

Ma courte conclusion était la suivante :

  • Octets privés = La mémoire que mon processus a demandée pour stocker les données.Une partie peut être paginée sur le disque ou non.C'est l'information que je cherchais.

  • Octets virtuels = Les octets privés, plus l'espace partagé avec d'autres processus pour les DLL chargées, etc.

  • Ensemble de travail = La partie de TOUTE la mémoire de mon processus qui n'a pas été paginée sur le disque.Le montant paginé sur le disque doit donc être (Virtuel - Ensemble de travail).

Merci à tous pour votre aide!

Si vous souhaitez utiliser la "Mémoire (Private Working Set)" comme indiqué dans le gestionnaire de tâches de Windows Vista, qui est l'équivalent de Process Explorer "WS Private Bytes", voici le code.Il est probablement préférable de lancer cette boucle infinie dans une tâche de thread/arrière-plan pour des statistiques en temps réel.

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

Pour obtenir la valeur offerte par le Gestionnaire des tâches, je tire mon chapeau à la solution de Mike Regan ci-dessus.Cependant un changement :ce n'est pas: perfCounter.NextValue()/1000; mais perfCounter.NextValue()/1024; (c'est à dire.un vrai kilo-octet).Cela donne la valeur exacte que vous voyez dans le Gestionnaire des tâches.

Voici une solution complète pour afficher «l'utilisation de la mémoire» (celle du gestionnaire de tâches, comme indiqué) de manière simple dans votre application WPF ou WinForms (dans ce cas, simplement dans le titre).Appelez simplement cette méthode dans le nouveau constructeur Window :

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

L'ensemble de travail n'est pas une bonne propriété à utiliser.D'après ce que j'ai compris, cela inclut tout ce que le processus peut toucher, même les bibliothèques partagées par plusieurs processus, vous voyez donc des octets comptés en double dans ce compteur.La mémoire privée est un bien meilleur compteur à examiner.

Je suggère de surveiller également la fréquence des défauts de page.Un défaut de page se produit lorsque vous essayez d'accéder à certaines données qui ont été déplacées de la mémoire physique vers un fichier d'échange et que le système doit lire la page du disque avant que vous puissiez accéder à ces données.

Est-ce une description juste ?J'aimerais partager ceci avec mon équipe, alors n'hésitez pas à me faire savoir si c'est incorrect (ou incomplet) :

Il existe plusieurs façons en C# de demander la quantité de mémoire utilisée par mon processus.

  • La mémoire allouée peut être gérée (par le CLR) ou non gérée.
  • La mémoire allouée peut être virtuelle (stockée sur disque) ou chargée (dans des pages RAM)
  • La mémoire allouée peut être privée (utilisée uniquement par le processus) ou partagée (par ex.appartenant à une DLL à laquelle d'autres processus font référence).

Compte tenu de ce qui précède, voici quelques façons de mesurer l’utilisation de la mémoire en C# :

1) Processus.VirtualMemorySize64() :renvoie toute la mémoire utilisée par un processus - gérée ou non, virtuelle ou chargée, privée ou partagée.

2) Processus.PrivateMemorySize64() :renvoie toute la mémoire privée utilisée par un processus - gérée ou non, virtuelle ou chargée.

3) Processus.WorkingSet64() :renvoie toute la mémoire privée chargée utilisée par un processus - gérée ou non gérée

4) GC.GetTotalMemory() :renvoie la quantité de mémoire gérée surveillée par le garbage collector.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top