web-dev-qa-db-fra.com

Rapports contradictoires sur l'utilisation totale de la mémoire de processus dans l'application C # Winforms

EDIT: La prime a expiré, mais si la communauté souhaite l'attribuer à quelqu'un, alors je choisis Raful Chizkiyahu.


J'ai une fuite de mémoire dans l'un de mes programmes C # Winforms, et j'aimerais représenter graphiquement son utilisation de la mémoire au fil du temps pour mieux comprendre ce qui pourrait être à l'origine de la fuite. Le problème est qu'aucune des commandes de diagnostic de mémoire habituelles ne correspond à ce que le Gestionnaire des tâches revendique comme sa mémoire consommée pour ce processus. J'ai supposé que cela était peut-être dû au fait que l'application utilisant du code non sécurisé/non géré n'était pas incluse dans le total.

Donc, pour essayer d'approfondir, j'ai créé une nouvelle application Winforms, très simple, avec juste une minuterie pour signaler l'utilisation de la mémoire en temps réel. J'utilise 5 étiquettes, chacune avec diverses fonctions (principalement trouvées à partir d'ici ): Environment.WorkingSet, GC.GetTotalMemory(false), GC.GetTotalMemory(true), Process.GetCurrentProcess().PrivateMemorySize64 et Process.GetCurrentProcess().WorkingSet64.

Étonnamment (ou peut-être pas, soupir), je ne parviens toujours pas à faire correspondre l'un de ces cinq chiffres avec le gestionnaire de tâches de Windows 10. Voici une capture d'écran:

pic

Donc, ce que je recherche essentiellement, c'est ce numéro de 5,1 Mo. Comment extraire sournoisement ce numéro caché du framework .NET?

Voici le code que j'ai dans la fonction Timer tick:

private void timer1_Tick(object sender, EventArgs e)
{
    //Refresh();
    label1.Text = "Environment.WorkingSet: " +  Environment.WorkingSet ;
    label2.Text = "GC.GetTotalMemory(false): " +    GC.GetTotalMemory(false) ;
    label3.Text = "GC.GetTotalMemory(true): " + GC.GetTotalMemory(true) ;
    Process proc = Process.GetCurrentProcess();
    label4.Text = "proc.PrivateMemorySize64: " +    proc.PrivateMemorySize64 ;
    label5.Text = "proc.WorkingSet64: " +       proc.WorkingSet64 ;
    proc.Dispose();
}

Comme cela peut être évident, j'ai essayé avec et sans la commande Refresh() en vain.


EDIT: La prime a expiré, mais si la communauté souhaite l'attribuer à quelqu'un, alors je choisis Raful Chizkiyahu.

8
Dan W

Vous avez besoin de meilleurs outils, TaskManager ne vous donnera une utilisation approximative de la mémoire qu'à un certain moment.

Si vous soupçonnez une fuite de mémoire, la méthode éprouvée consiste à effectuer des vidages de mémoire (instantanés) de l'application.

Un instantané doit être pris au démarrage de l'application, puis à des intervalles ultérieurs. Si la mémoire augmente lentement, vous devrez attendre un peu entre chaque instantané. Vous pouvez ensuite comparer les instantanés. Cette méthode vous permet d'analyser et de comparer les allocations d'objets, le nombre d'objets, même la mémoire non gérée.

Microsoft a écrit un guide pour l'outil d'utilisation de la mémoire intégré à Visual Studio . Dans la plupart des cas, cela devrait suffire à identifier la fuite.

Si vous trouvez que les outils intégrés sont limités, jetez un œil à ceci question SO et aux autres liés dans la barre latérale.

0
Alexander Pope