Connaître la consommation mémoire d’un processus
Après une discussion sur Twitter à propos de la consommation de mémoire de MariaDB « out-of-the-box » (au final MySQL consomme pareil), s’est posée la question de savoir comment afficher la quantité de mémoire utilisée par un seul processus. Pas évident, mais pas impossible.
Attention : je suis loin d’être un expert dans le domaine du noyau Linux, et encore moins de la gestion de la mémoire vive. Donc si je dis d’énormes bêtises qu’il faut corriger, faites-moi signe.
De multiples valeurs possibles
Mémoire virtuelle, mémoire partagée, mémoire réservée… les valeurs possibles sont différentes suivant qu’on regarde de l’intérieur ou de l’extérieur du processus. Pour compliquer un peu les choses, la mémoire est géré par « pages », et donc ces pages ne sont pas nécessairement pleines des données qui nous concernent.
vraiment pas clair les données de top
La mémoire réservée, un indicateur potable
Potable dans le sens qu’il ne traduit pas nécessairement la valeur réelle à l’instant T de la mémoire consommée, mais la mémoire maximale utilisable théoriquement par un processus. Par exemple, je teste HHVM en ce moment, il annonce 126Mo de réservé, mais entre avant et après sont lancement, je n’ai que grosso modo 50Mo de mangé sur la mémoire totale. Juste avant de le couper, il avait déjà tourné pendant plusieurs jours, et la mémoire totale avoisinait les 300Mo soit environ 70Mo de plus. 50+70 = 120, soit pas loin des 126Mo réservés. Mais ce n’est pas une mesure au doigt mouillé qu’on cherche ici.
ps, l’outil d’information imbuvable mais complet
Pour extraire la valeur de la quantité de mémoire réservée, je me repose sur la valeur retournée par ps. Cette valeur est un pourcentage de la mémoire totale, alors il faudra un peu de travail pour arriver à un résultat potable. J’utilise les switches aux pour être sûr d’avoir tous les processus, car on pourrait avoir besoin de l’info sur un processus qui ne nous appartient pas.
1 2 3 4 5 6 7 8 9 10 11 |
ps aux |head USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 10652 692 ? Ss janv.23 0:26 init [2] root 2 0.0 0.0 0 0 ? S janv.23 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S janv.23 0:39 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S janv.23 0:00 [kworker/u:0] root 6 0.0 0.0 0 0 ? S janv.23 0:00 [migration/0] root 7 0.0 0.0 0 0 ? S janv.23 0:17 [watchdog/0] root 8 0.0 0.0 0 0 ? S janv.23 0:01 [migration/1] root 9 0.0 0.0 0 0 ? S janv.23 0:18 [kworker/1:0] root 10 0.0 0.0 0 0 ? S janv.23 0:28 [ksoftirqd/1] |
free pour avoir la mémoire totale
free est un utilitaire renseignant sur l’état de la mémoire : quantité totale, quantité utilisée, quantité restante… j’utilise le switch -m pour avoir les valeurs en méga-octets.
1 2 3 4 5 |
free -m total used free shared buffers cached Mem: 748 649 98 0 129 298 -/+ buffers/cache: 221 527 Swap: 952 10 942 |
grep et awk pour filtrer le tout
On a déjà vu ces outils dans l’article sur les stats Freebox : grep va nous permettre d’isoler la ligne du processus qu’on veut, et awk seulement le pourcentage réservé affiché dans cette ligne.
Le tout dans un script
Plusieurs lignes sont nécessaires, alors on va tout mettre dans un fichier, qu’on appellera, au pif, memoire.sh (très original) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#!/bin/bash #Vérification du nombre d'arguments # if [[ $# -eq 0 || $# -gt 1 ]]; then echo "Usage : $0 [PROCESS_NAME]" exit 1 fi TOTALMEM=`free -m|grep "Mem"|awk '{printf $2}'` PROCESSPID=`pidof $1` if [[ $PROCESSPID -ne "" ]]; then MEMORYPID=`ps aux |grep $PROCESSPID |grep -v grep|awk '{printf $4}'` REALMEMORY=`echo "${MEMORYPID}*${TOTALMEM}*0.01"|bc` echo $REALMEMORY fi |
Une fois n’est pas coutume je fais quelques vérifications d’usage : est-ce qu’on lui passe bien un seul argument, est-ce que le processus existe. Si c’est le cas, je stocke les résultats des recherches de mémoire réservée ainsi que la mémoire totale. Enfin je renvoie le calcul de mémoire réservée. D’ailleurs, j’ai du installer bc pour l’occasion car Bash ne sait pas faire de calcul en virgule flottante.
Après avoir fait ça et en être tout fier, j’ai un peu ragé, parce que j’ai fini par tomber sur un outil bien plus précis que le mien, qui ne fait finalement qu’extraire et recalculer simplement une valeur existante.
smem, l’artillerie (très) lourde
smem est un outil permettant d’afficher quantité d’informations sur la mémoire vive. Je l’ai découvert dans une étable bien connue, et je me suis renseigné en plus sur le site officiel de l’outil. Très complet, je vous invite à lire les infos du site officiel pour en savoir plus, notamment sur la Proportional Set Size, plus représentative finalement de ce que j’utilise, la Resident Set Size.
Je ne l’ai pas testé moi-même pour une bonne raison : s’il est packagé pour Debian, la quantité de dépendances nécessaires est énorme, et surtout lié au fait de pouvoir afficher des graphiques dans les environnements qui le supporte. Quand on voit ça :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
sudo apt-get install smem [sudo] password for seboss666: Lecture des listes de paquets... Fait Construction de l'arbre des dépendances Lecture des informations d'état... Fait Les paquets supplémentaires suivants seront installés : blt fontconfig fonts-lyx gir1.2-glib-2.0 hicolor-icon-theme libatk1.0-0 libatk1.0-data libblas3 libcairo2 libdatrie1 libgdk-pixbuf2.0-0 libgdk-pixbuf2.0-common libgfortran3 libgirepository-1.0-1 libgl1-mesa-glx libglade2-0 libglapi-mesa libgtk2.0-0 libgtk2.0-bin libgtk2.0-common liblapack3 libpango1.0-0 libthai-data libthai0 libutempter0 libx11-xcb1 libxcb-glx0 libxcb-render0 libxcb-shape0 libxcb-shm0 libxcursor1 libxft2 libxi6 libxinerama1 libxss1 libxtst6 libxv1 libxxf86dga1 libxxf86vm1 python-cairo python-dateutil python-gi python-glade2 python-gobject python-gobject-2 python-gtk2 python-matplotlib python-matplotlib-data python-numpy python-pyparsing python-tk python-tz tcl8.5 tk8.5 x11-utils xbitmaps xterm Paquets suggérés : blt-demo librsvg2-common gvfs ttf-baekmuk ttf-arphic-gbsn00lp ttf-arphic-bsmi00lp ttf-arphic-gkai00mp ttf-arphic-bkai00mp python-gi-cairo python-gtk2-doc python-gobject-2-dbg dvipng ipython python-configobj python-excelerator python-matplotlib-doc python-qt4 python-scipy python-traits python-wxgtk2.8 texlive-extra-utils texlive-latex-extra python-numpy-doc python-numpy-dbg python-nose python-dev gfortran tix python-tk-dbg tcl-tclreadline mesa-utils xfonts-cyrillic Les NOUVEAUX paquets suivants seront installés : blt fontconfig fonts-lyx gir1.2-glib-2.0 hicolor-icon-theme libatk1.0-0 libatk1.0-data libblas3 libcairo2 libdatrie1 libgdk-pixbuf2.0-0 libgdk-pixbuf2.0-common libgfortran3 libgirepository-1.0-1 libgl1-mesa-glx libglade2-0 libglapi-mesa libgtk2.0-0 libgtk2.0-bin libgtk2.0-common liblapack3 libpango1.0-0 libthai-data libthai0 libutempter0 libx11-xcb1 libxcb-glx0 libxcb-render0 libxcb-shape0 libxcb-shm0 libxcursor1 libxft2 libxi6 libxinerama1 libxss1 libxtst6 libxv1 libxxf86dga1 libxxf86vm1 python-cairo python-dateutil python-gi python-glade2 python-gobject python-gobject-2 python-gtk2 python-matplotlib python-matplotlib-data python-numpy python-pyparsing python-tk python-tz smem tcl8.5 tk8.5 x11-utils xbitmaps xterm 0 mis à jour, 58 nouvellement installés, 0 à enlever et 0 non mis à jour. Il est nécessaire de prendre 31,8 Mo dans les archives. Après cette opération, 104 Mo d'espace disque supplémentaires seront utilisés. Souhaitez-vous continuer [O/n] ? n Annulation. |
On comprend vite pourquoi j’ai annulé. Non pas que l’espace disque soit restreint à ce point, mais j’aime garder un environnement « optimisé », et installer tout ça alors que ça ne sert qu’à un seul outil, en plus sans interface graphique (donc plusieurs paquets sont strictement inutiles), alors je m’en passe. Mais si vous n’avez pas ces critères, foncez, c’est du bon outil.