GNU/Linux >> Tutoriels Linux >  >> Linux

Comment détecter par programmation le nombre d'octets alloués par processus sur Heap ?

Je pense que mallinfo() est ce que vous voulez :

#include <malloc.h>


struct mallinfo *info;

info = mallinfo();

printf ("total allocated space:  %llu bytes\n", info->uordblks);
printf ("total free space:       %llu bytes\n", info->fordblks);

La structure struct mallinfo est technique et spécifique à l'implémentation de malloc(). Mais l'information que vous voulez est là-dedans. Voici comment je signale les valeurs :

mallinfo.arena = "Total Size (bytes)" 
mallinfo.uordblks = "Busy size (bytes)" 
mallinfo.fordblks = "Free size (bytes)" 
mallinfo.ordblks = "Free blocks (count)" 
mallinfo.keepcost = "Top block size (bytes)" 
mallinfo.hblks = "Blocks mapped via mmap() (count)" 
mallinfo.hblkhd = "Bytes mapped via mmap() (bytes)"

Ces deux éléments ne sont prétendument pas utilisés, mais ils semblent changer sur mon système et pourraient donc être valides :

mallinfo.smblks = "Fast bin blocks (count)"
mallinfo.fsmblks = "Fast bin bytes (bytes)"

Et l'autre valeur intéressante est renvoyée par "sbrk(0)"


Il existe plusieurs possibilités.

Quelle est la précision dont vous avez besoin ? Vous pouvez obtenir des données utiles via cat /proc/${PID}/status | grep VmData .

Vous pouvez #define votre propre malloc() , realloc() , calloc() , et libre() fonctions, en enveloppant les fonctions réelles derrière votre propre compteur. Vous pouvez faire des choses vraiment intéressantes ici avec __FILE__, __LINE__ et __func__ pour faciliter l'identification des fuites de base dans des tests simples. Mais cela n'instrumentera que votre propre code !

(De même, vous pouvez également redéfinir l'opérateur new par défaut et suppression de l'opérateur méthodes, à la fois des variantes de tableau et non-tableau, et les deux lançant des variantes std::bad_alloc et std::nothrow_t. Encore une fois, cela n'instrumentera que votre propre code !)

(Attention :sur la plupart des systèmes C++, nouveau invoque finalement malloc() . Ce n'est pas nécessaire. Surtout avec nouveau en place ! Mais généralement nouveau utilise malloc() . (Ou il opère sur une région de mémoire qui a été préalablement malloc()'ed .) Sinon, vous vous lanceriez dans des trucs vraiment funky avec plusieurs gestionnaires de tas...)

Vous pouvez utiliser sbrk(0) pour voir où le segment de données est actuellement défini. Ce n'est pas si génial. C'est une mesure très grossière, et elle ne tient pas compte des trous (régions de mémoire inutilisées) dans le tas. (Vous êtes bien mieux avec le VmData ligne de /proc/${PID}/status .) Mais si vous cherchez juste une idée générale...

Vous pouvez piéger malloc()/free()/etc en écrivant votre propre bibliothèque partagée et en forçant votre processus à l'utiliser à la place des versions réelles via LD_PRELOAD . Vous pouvez utiliser dlopen()/dlsym() pour charger et invoquer le *real* malloc()/free()/etc . Cela fonctionne très bien. Le code d'origine n'est pas modifié, pas même recompilé. Mais soyez conscient des situations réentrantes lors du codage de cette bibliothèque, et que votre processus invoquera initialement malloc()/calloc()/realloc() avant dlopen()/dlsym() peut terminer le chargement des fonctions réelles.

Vous pouvez consulter des outils comme Valgrind , même si cela vise davantage les fuites de mémoire.

Là encore, peut-être mtrace() est ce que tu veux ? Ou __malloc_hook ? Très propriétaire (GNU) &non standard... Mais vous êtes tagué "Linux"...


Il n'y a pas de processus automatique facile façon de le faire, si c'est ce que vous demandez. Vous devez essentiellement suivre manuellement les allocations de tas vous-même à l'aide d'une variable de compteur. Le problème est qu'il est difficile de contrôler quelles parties de votre programme allouent de la mémoire sur le tas, surtout si vous utilisez beaucoup de bibliothèques hors de votre contrôle. Pour compliquer davantage les choses, il existe deux façons pour un programme d'allouer de la mémoire de tas :new ou malloc . (Sans parler des appels directs au système d'exploitation comme sbrk .)

Vous pouvez remplacer l'opérateur global new , et faites en sorte que chaque appel à nouveau augmente un décompte global. Cependant, cela n'inclura pas nécessairement les moments où votre programme appelle malloc , ou lorsque votre programme utilise des new spécifiques à la classe passer outre. Vous pouvez également remplacer malloc à l'aide d'une macro, mais ce n'est pas nécessairement portable. Et vous devrez également remplacer toutes les variantes de malloc , comme realloc , calloc , etc. Tout cela est encore compliqué par le fait que sur certaines implémentations, new lui-même peut appeler malloc .

Donc, essentiellement, il est très difficile de le faire correctement à partir de votre programme. Je recommanderais plutôt d'utiliser un outil de profilage de mémoire.


Linux
  1. Comment installer vtop sur Linux

  2. Comment détecter le changement d'adresse IP par programmation sous Linux ?

  3. Comment obtenir l'ID de processus du processus d'arrière-plan ?

  4. Comment vérifier la taille du tas pour un processus sous Linux

  5. Comment implémenter malloc déterministe

Comment tuer un processus zombie sous Linux

Comment tuer un processus sous Linux

Comment tuer un processus sous Linux

Comment compter les lignes dans un document ?

Plus précisément, comment fork() gère-t-il la mémoire allouée dynamiquement à partir de malloc() sous Linux ?

comment vérifier la taille du tas allouée pour jvm par linux