Question Qu'est-ce qu'un octet privé, un octet virtuel, un jeu de travail?


J'essaye d'employer l'utilité de fenêtres de perfmon pour déboguer des fuites de mémoire dans un processus.

C'est ainsi que perfmon explique les termes:

Jeu de travail 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 récemment touchées par les threads dans le processus. Si la mémoire disponible sur l'ordinateur dépasse un seuil, les pages restent 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 tronquées à partir des jeux 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.

Octets virtuels 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 mémoire principale. L'espace virtuel est fini 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 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 a des fuites puisqu'il n'implique aucune bibliothèque partagée et que les fuites, si elles se produisent, viendront du processus lui-même?

Quelle est la quantité totale de mémoire consommée par le processus? Est-ce que c'est les octets virtuels ou est-ce la somme des octets virtuels et du jeu 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?


411
2017-12-31 06:16


origine


Réponses:


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 aucune d'elles n'est vraiment appropriée pour déboguer une fuite de mémoire.

Octets privés se référer à la quantité de mémoire que le processus exécutable a demandé - pas nécessairement le montant en train d'utiliser. 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 la capture - ils n'excluent pas nécessairement la mémoire alloué 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 sont également ne pas mémoire exclusivement physique; ils peuvent être recherché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).

Jeu de travail se réfère au total physique mémoire (RAM) 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. Il s'agit donc d'une mesure encore moins précise que les octets privés. C'est la même valeur qui est rapportée dans "Mem Usage" du Gestionnaire des tâches et a été la source de quantités infinies de confusion ces dernières années. La mémoire dans l'ensemble de travail est "physique" dans le sens où elle peut être adressée sans erreur de page; cependant, la liste de pages en attente est aussi toujours physiquement en mémoire, mais pas indiqué dans le jeu de travail, et c'est pourquoi vous pourriez voir le "Mem Usage" tomber soudainement lorsque vous réduisez une application.

Octets virtuels sont le total espace d'adressage virtuel 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 forte charge augmentera sensiblement la mémoire de la machine.

Donc, les relations sont:

  • Les octets privés sont ceux que votre application a réellement alloués, mais incluent l'utilisation du fichier d'échange;
  • Working Set est les octets privés non paginés plus les fichiers mappés en mémoire;
  • Les octets virtuels sont l'ensemble de travail plus les octets privés et la liste de réserve paginés.

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, conduisant à des faux positifs potentiels 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 partagé modules, ce qui conduit à 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 sont un raisonnable approximation de la quantité de mémoire que votre exécutable utilise et peut être utilisé pour aider affiner une liste de candidats potentiels pour une fuite de mémoire; Si vous voyez le nombre croître et croître constamment et sans fin, vous voudrez 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 fuites de mémoire dans Windows est en fait Visual Studio (le lien va à la page sur l'utilisation de VS pour les fuites de mémoire, pas la page du produit). Rational Purifier est une autre possibilité. Microsoft a également un plus général document sur les meilleures pratiques à propos de ce sujet. Il y a plus d'outils listés dans ce question précédente.

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


427
2017-12-31 18:11



Vous ne devez pas essayer d'utiliser perfmon, le gestionnaire de tâches ou tout autre 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 fuites de mémoire.

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

Vous posez des questions sur une recommandation d'outil: Je recommande Memory Validator. Capable de surveiller des 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.


9
2018-02-05 17:25



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

Un bon aperçu de la gestion de la mémoire Windows est disponible dans la vidéo "Les mystères de la gestion de la mémoire révélés»sur MSDN: Il couvre plus de sujets que nécessaire pour suivre les fuites de mémoire (par exemple la gestion des ensembles de travail) mais donne suffisamment de détails sur les sujets pertinents.


Pour vous donner une idée du problème avec les descriptions de compteurs perfmon, voici l'histoire à l'intérieur des octets privés de "Compteur de performance en octets privés - Attention!"sur MSDN:

Q: Quand un octet privé n'est 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 qui a été allouée dans le fichier d'échange pour contenir le contenu de la mémoire privée dans le cas où elle est permutée. Note: J'évite le mot "reserved" en raison d'une possible confusion avec la mémoire virtuelle dans l'état réservé qui n'est pas engagé.


De "Planification du rendement"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 coûteuse 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 DLLs non gérées (traditionnelles) constitue généralement une statique C ++ et est de l'ordre de 5% de l'ensemble de travail total de la DLL.


6
2017-11-13 01:17



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 fil de discussion est que libérer de petites allocations ne se reflète pas dans les octets privés ou dans l'ensemble de travail.

Longue histoire courte:

si j'appelle

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

alors les octets privés reflètent seulement l'allocation, pas l'allocation.

si j'appelle

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

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


5
2018-04-28 08:39