Qu’est-ce que les octets privés, les octets virtuels, l’ensemble de travail?

J’essaie d’utiliser l’utilitaire perfmon windows pour déboguer les memory leaks dans un processus.

Voici comment perfmon explique les termes:

Working Set est la taille actuelle, en octets, de l’ensemble de travail de ce processus. L’ensemble de travail est l’ensemble des pages de mémoire touchées récemment par les threads du processus. Si la mémoire disponible sur l’ordinateur dépasse un seuil, les pages restnt dans le groupe de travail d’un processus même si elles ne sont pas utilisées. Lorsque la mémoire libre est inférieure à un seuil, les pages sont supprimées des ensembles de travail. S’ils sont nécessaires, ils seront ensuite remis en défaut dans le groupe de travail avant de quitter la mémoire principale.

Virtual Bytes est la taille actuelle, en octets, de l’espace d’adressage virtuel utilisé par le processus. L’utilisation de l’espace d’adressage virtuel n’implique pas nécessairement l’utilisation correspondante des pages de disque ou de la mémoire principale. L’espace virtuel est fini et le processus peut limiter sa capacité à charger des bibliothèques.

Private Bytes est la taille actuelle, en octets, de la mémoire allouée par ce processus et qui ne peut pas être partagée avec d’autres processus.

Ce sont les questions que j’ai:

Est-ce que ce sont les octets privés que je devrais mesurer pour être sûr que le processus présente des fuites, car il n’implique aucune bibliothèque partagée et que toute fuite, si elle se produit, proviendra du processus lui-même?

Quelle est la mémoire totale consommée par le processus? Est-ce les octets virtuels ou est-ce la sum des octets virtuels et de l’ensemble de travail?

Existe-t-il une relation entre octets privés, ensemble de travail et octets virtuels?

Y a-t-il d’autres outils qui donnent une meilleure idée de l’utilisation de la mémoire?

La réponse courte à cette question est qu’aucune de ces valeurs n’est un indicateur fiable de la quantité de mémoire utilisée par un exécutable, et aucune n’est vraiment appropriée pour le débogage d’une fuite de mémoire.

Les octets privés font référence à la quantité de mémoire demandée par l’ exécutable du processus – pas nécessairement la quantité réellement utilisée . Ils sont “privés” car ils excluent (généralement) les fichiers mappés en mémoire (c’est-à-dire les DLL partagées). Mais – voici le problème – ils n’excluent pas nécessairement la mémoire allouée par ces fichiers . Il n’y a aucun moyen de savoir si un changement dans les octets privés était dû à l’exécutable lui-même ou à une bibliothèque liée. Les octets privés ne sont pas non plus exclusivement de la mémoire physique; ils peuvent être transférés sur disque ou dans la liste de pages en attente (c.-à-d. qu’ils ne sont plus utilisés, mais pas encore paginés).

Working Set fait référence à la mémoire physique totale (RAM) utilisée par le processus. Toutefois, contrairement aux octets privés, cela inclut également les fichiers mappés en mémoire et diverses autres ressources, ce qui en fait une mesure encore moins précise que les octets privés. C’est la même valeur qui est rapscope dans “Mem Usage” du Gestionnaire des tâches et a été source de confusion sans fin au cours des dernières années. La mémoire du jeu de travail est “physique” en ce sens qu’elle peut être adressée sans erreur de page; Cependant, la liste des pages en attente est également toujours physiquement en mémoire mais n’est pas signalée dans le jeu de travail. C’est pourquoi vous pouvez voir que “Mem Usage” est soudainement perdu lorsque vous réduisez une application.

Les octets virtuels sont l’ espace d’adressage virtuel total occupé par l’ensemble du processus. C’est comme le jeu de travail, en ce sens qu’il inclut les fichiers mappés en mémoire (DLL partagées), mais il inclut également les données de la liste en attente et les données qui ont déjà été extraites et qui se trouvent quelque part dans un fichier page. Le nombre total d’octets virtuels utilisés par chaque processus sur un système soumis à une charge importante augmente considérablement la mémoire de la machine.

Donc les relations sont:

  • Les octets privés sont ce que votre application a réellement alloué, mais incluent l’utilisation de fichiers d’échange.
  • Working Set est constitué des octets privés non paginés et des fichiers mappés en mémoire.
  • Les octets virtuels sont l’ensemble de travail plus les octets privés paginés et la liste d’attente.

Il y a un autre problème ici; tout comme les bibliothèques partagées peuvent allouer de la mémoire à l’intérieur de votre module d’application, entraînant des faux positifs potentiels dans les octets privés de votre application, votre application peut également allouer de la mémoire à l’intérieur des modules partagés , entraînant des faux négatifs . Cela signifie qu’il est possible que votre application ait une fuite de mémoire qui ne se manifeste jamais dans les octets privés. Peu probable, mais possible.

Les octets privés représentent une approximation raisonnable de la quantité de mémoire utilisée par votre exécutable et peuvent être utilisés pour affiner une liste de candidats potentiels à une fuite de mémoire. Si vous voyez le nombre grandir et croître constamment et à l’infini, vous voudriez vérifier ce processus pour une fuite. Cela ne peut cependant pas prouver qu’il y a ou non une fuite.

L’un des outils les plus efficaces pour détecter / corriger les memory leaks dans Windows est en réalité Visual Studio (le lien va à la page sur l’utilisation de VS pour les memory leaks, pas la page du produit). Rational Purify est une autre possibilité. Microsoft dispose également d’un document sur les meilleures pratiques à ce sujet. Il y a plus d’outils listés dans cette question précédente .

J’espère que cela efface quelques petites choses! Le suivi des memory leaks est l’une des tâches les plus difficiles à effectuer lors du débogage. Bonne chance.

Vous ne devez pas essayer d’utiliser perfmon, le gestionnaire de tâches ou tout autre outil de ce type pour déterminer les memory leaks. Ils sont bons pour identifier les tendances, mais pas grand chose d’autre. Les chiffres qu’ils rapportent en termes absolus sont trop vagues et agrégés pour être utiles pour une tâche spécifique telle que la détection des memory leaks.

Une réponse précédente à cette question a donné une grande explication de ce que sont les différents types.

Vous posez des questions sur une recommandation d’outil: je recommande le validateur de mémoire. Capable de surveiller les applications qui génèrent des milliards d’allocations de mémoire.

http://www.softwareverify.com/cpp/memory/index.html

Disclaimer: J’ai conçu Memory Validator.

La définition des compteurs de perfmon a été rompue depuis le début et semble, pour une raison quelconque, trop difficile à corriger.

Un bon aperçu de la gestion de la mémoire Windows est disponible dans la vidéo ” Mysteries of Memory Management Revealed ” sur MSDN: elle couvre plus de sujets que nécessaire pour suivre les memory leaks (par exemple la gestion des postes de travail) mais donne suffisamment de détails dans les rubriques pertinentes.


Pour vous donner une idée du problème rencontré avec les descriptions des compteurs perfmon, voici l’histoire interne des octets privés de ” Compteur de performance d’ octets privés – Attention! ” Sur MSDN:

Q: Quand un octet privé n’est-il pas un octet privé?

A: quand il n’est pas résident

Le compteur Bytes privés indique la charge de validation du processus. C’est-à-dire la quantité d’espace allouée dans le fichier d’échange pour contenir le contenu de la mémoire privée en cas de remplacement. Remarque: J’évite le mot “réservé” en raison d’une confusion possible avec la mémoire virtuelle dans l’état réservé qui n’est pas validée.


De ” Performance Planning ” sur MSDN:

3.3 octets privés

3.3.1 Description

La mémoire privée est définie comme la mémoire allouée à un processus qui ne peut pas être partagé par d’autres processus. Cette mémoire est plus chère que la mémoire partagée lorsque plusieurs processus de ce type sont exécutés sur une machine. La mémoire privée dans les DLL non gérées (traditionnelles) constitue généralement une statistique C ++ et est de l’ordre de 5% de l’ensemble de travail total de la DLL.

Il y a une discussion intéressante ici: http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/307d658a-f677-40f2-bdef-e6352b0bfe9e/ Ma compréhension de ce sujet est que la libération de petites allocations est non reflété dans les octets privés ou ensemble de travail.

Longue histoire courte:

si j’appelle

p=malloc(1000); free(p); 

alors les octets privés ne reflètent que l’allocation, pas la désallocation.

si j’appelle

 p=malloc(>512k); free(p); 

les octets privés reflètent alors correctement l’allocation et la désallocation.