J'essaie d'utiliser l'utilitaire perfmon windows pour déboguer des fuites de mémoire dans un processus.
Voici comment perfmon explique les termes:
Working Set est la taille actuelle, en octets, du jeu de travail de ce processus. Le jeu 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 est supérieure à un seuil, les pages sont conservées dans le jeu de travail d'un processus, même si elles ne sont pas utilisées. Lorsque la mémoire disponible tombe en dessous d'un seuil, les pages sont découpées à partir des jeux de travail. S'ils sont nécessaires, ils seront alors réintégrés dans le poste 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 d'un 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 limité et le processus peut limiter sa capacité à charger des bibliothèques.
Octets privés est la taille actuelle, en octets, de la mémoire allouée par ce processus et ne pouvant ê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 a des fuites puisqu'il ne comporte pas de bibliothèques partagées et que les fuites éventuelles proviendront du processus lui-même?
Quelle est la mémoire totale consommée par le processus? S'agit-il des octets virtuels ou est-ce la somme des octets virtuels et de l'ensemble de travail?
Existe-t-il une relation entre les octets privés, les jeux de travail et les octets virtuels?
Existe-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 que aucune de ces valeurs n'est un indicateur fiable de la quantité de mémoire réellement utilisée par un exécutable et qu'aucune d'entre elles 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 que l'exécutable de processus a demandée - pas nécessairement à la quantité. il utilise réellement . 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 piège - ils n'excluent pas nécessairement la mémoire allouée par ces fichiers . Il n'y a aucun moyen de savoir si une modification d'octets privés est due à l'exécutable lui-même ou à une bibliothèque liée. Les octets privés sont également pas exclusivement de la mémoire physique; ils peuvent être recherchés sur le disque ou dans la liste de pages en attente (c’est-à-dire qu’ils ne sont plus utilisés, mais pas encore recherchés non plus).
Ensemble de travail fait référence à la mémoire totale physique utilisée par le processus. Cependant, 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. Cette valeur est identique à celle indiquée dans "Mem Usage" du Gestionnaire des tâches et a été source de confusion sans fin ces dernières années. La mémoire dans le groupe de travail est "physique" dans le sens où elle peut être adressée sans défaut de page; Cependant, la liste de pages en veille est également toujours physiquement en mémoire mais n'est pas signalée dans le jeu de travail; application.
Les octets virtuels représentent le total espace d'adressage virtuel occupé par l'ensemble du processus. Cela ressemble au jeu de travail, dans le sens où il inclut des fichiers mappés en mémoire (DLL partagées), mais il inclut également des données dans la liste de veille et des données qui ont déjà été paginées et qui se trouvent quelque part dans un fichier d'échange. Le nombre total d'octets virtuels utilisés par chaque processus sur un système soumis à une charge de travail élevée va ajouter beaucoup plus de mémoire que la machine.
Les relations sont donc:
Il y a un autre problème ici; De même que les bibliothèques partagées peuvent allouer de la mémoire à l’intérieur de votre module d’application, ce qui peut entraîner des faux positifs signalés dans les octets privés de votre application, votre application peut également finir par allouer de la mémoire à l’intérieur du modules partagés , conduisant à de faux négatifs . Cela signifie que votre application peut en réalité avoir une fuite de mémoire qui ne se manifeste jamais du tout dans les octets privés. Peu probable, mais possible.
Les octets privés sont une approximation raisonnable de la quantité de mémoire utilisée par votre exécutable et peuvent être utilisés pour vous aider à réduire une liste de candidats potentiels pour une fuite de mémoire; Si vous voyez que le nombre augmente constamment et sans cesse, vous voudrez vérifier ce processus pour une fuite. Cela ne peut toutefois pas prouver qu'il y a ou non une fuite.
L’un des outils les plus efficaces pour détecter/corriger les fuites de mémoire dans Windows est en fait Visual Studio (le lien renvoie à la page relative à l’utilisation de VS pour les fuites de mémoire, pas à la page du produit). Rational Purify est une autre possibilité. Microsoft a également un plus général document sur les meilleures pratiques à ce sujet. Il y a plus d'outils énumérés dans cette question précédente .
J'espère que cela efface quelques points! Le traçage des fuites de mémoire est l’une des tâches les plus difficiles à effectuer lors du débogage. Bonne chance.
N'essayez pas d'utiliser perfmon, un gestionnaire de tâches ou un outil de ce type pour déterminer les fuites de mémoire. 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 à une tâche spécifique telle que la détection de fuite de mémoire.
Une réponse précédente à cette question a donné une grande explication de ce que sont les différents types.
Vous demandez une recommandation d’outil: je recommande Memory Validator. Capable de surveiller les applications qui font 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 performance a été brisée depuis le début et semble trop difficile à corriger.
Une bonne vue d'ensemble de la gestion de la mémoire Windows est disponible dans la vidéo " Mystères de la gestion de la mémoire révélés " sur MSDN: il couvre plus sujets nécessaires pour suivre les fuites de mémoire (par exemple, la gestion des postes de travail), mais donne suffisamment de détails dans les sujets correspondants.
Pour vous donner une idée du problème posé par les descriptions de compteurs perfmon, voici l’histoire de base des octets privés de " Performances des octets privés - Attention! "sur MSDN:
Q: Quand un octet privé n'est-il pas un octet privé?
A: Quand ce n'est pas résident.
Le compteur Octets 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 au cas où il serait échangé. Remarque: J'évite le mot "réservé" en raison d'une confusion possible avec la mémoire virtuelle à l'état réservé qui n'est pas validée.
De " Planification des performances " 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ée par d'autres processus. Cette mémoire coûte plus cher que la mémoire partagée lorsque plusieurs processus de ce type s'exécutent sur une machine. La mémoire privée dans les dll (traditionnelles) non gérées constitue généralement une statique C++ et est de l’ordre de 5% de l’ensemble de travail de la dll.
Il existe une discussion intéressante ici: http://social.msdn.Microsoft.com/Forums/en-US/vcgeneral/thread/307d658a-f677-40f2-bdef-e6352b0bfe9e/ Ma compréhension de cette question thread est que la libération de petites allocations n'est pas reflétée dans les octets privés ou les groupes 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);
alors les octets privés reflètent correctement l'allocation et la désallocation.