Outils pour utilisateurs

Outils du site


expert:analyser_usage_memoire_vive

Analyser l'utilisation de la mémoire vive

Si vous êtes un utilisateur habituel de systèmes Linux vous avez sans doute le réflexe d'utiliser la commande “top” ou “htop” pour jeter un œil sur l'utilisation des ressources du système par les programmes. Ces utilitaires fournissent de nombreuses informations parmi lesquelles figure l'utilisation de la mémoire vive. Dans certaines conditions ces informations peuvent vous donner une vue incorrecte de l'utilisation de la mémoire vive, et offrent peu de détails. Pour une analyse plus fine il existe des outils plus appropriés comme smem.

Pourquoi surveiller l'utilisation de la mémoire vive ?

La mémoire vive est abordable et souvent présente en quantité confortable, mais parallèlement les environnements de bureaux et de nombreuses applications deviennent de plus en plus avides de cette denrée. Si on y ajoute un bogue courant nommé “memory leak” (“fuite de mémoire”), il est intéressant de pouvoir identifier les ogres qui dévorent votre mémoire vive.
Une autre application est la comparaison de plusieurs programmes accomplissant des tâches équivalentes, par exemple Evolution vs Thunderbird, Amarok vs rhythmbox vs banshee ou comme c'est la mode en ce moment Firefox vs Chromium. Pour avoir une idée claire de l'utilisation de la mémoire vive par un de ces programmes il faut prendre en compte l'ensemble des processus lancés (et pas seulement celui qui arrive en tête de classement dans la sortie de "top"), et pouvoir identifier si une utilisation anormale provient d'un appel à une bibliothèque externe, une extension, ou autre. Un navigateur Internet moderne lance un grand nombre de processus lors de son utilisation, et fait appel à de très nombreuses bibliothèques, faire un simple “grand total” de l'utilisation de la mémoire vive résidante pour un tel programme n'est pas toujours simple.

Il existe de nombreuses façons d'avoir un aperçu de l'utilisation de la mémoire vive sur un système Linux depuis la lecture directe dans /proc/ jusqu'aux outils de débogage spécialisés comme valgrind, en passant par top et htop, vmstat, pmap, memstat ou smem. Ici on ne se placera pas dans l'optique d'un programmeur chevronné pour lequel l'utilisation d'un programme comme valgrind sera sans problème, les méthodes décrites sont accessibles à tout utilisateur de système Linux un peu curieux et attentif à son système.

Le logiciel de surveillance du système "ksysguard" de KDE. Pratique quand on a une interface graphique et un environnement de bureau installé :

Lire les informations à la source : /proc/

Parmi les répertoires présents sur votre système vous n'avez peut être jamais accordé une grande attention à /proc, il s'agit d'une système de fichiers virtuels qui sont des interfaces avec le noyau Linux, c'est ici que de nombreux utilitaires comme “top” viennent chercher leurs informations. Ici vous pouvez lire directement ces informations, mais le plus souvent sous une forme brute et peu compréhensible. C'est pour cette raison qu'on utilise souvent un programme qui se chargera de la mise en forme du résultat présenté.
Pour notre sujet à savoir l'utilisation de la mémoire vive par un programme donné, c'est /proc/$PID/maps qui va nous intéresser. “$PID” représente le numéro de processus (PID) du programme visé.
Voici un aperçu très abrégé du contenu de /proc :

$ ls -l /proc
[...]
dr-xr-xr-x  7 tux  tux                0  1 déc.  10:10 5086
dr-xr-xr-x  7 root root               0  1 déc.  09:10 559
dr-xr-xr-x  7 root root               0  1 déc.  09:10 561
dr-xr-xr-x  7 root root               0  1 déc.  09:10 565
dr-xr-xr-x  7 tux  tux                0  1 déc.  10:12 5986
[...]
-r--r--r--  1 root  root              0  1 déc.  10:55 meminfo
-r--r--r--  1 root  root              0  1 déc.  10:55 swaps
-r--------  1 root  root              0  1 déc.  10:55 vmallocinfo
-r--r--r--  1 root  root              0  1 déc.  10:55 vmstat

Les valeurs numériques qui terminent certaines lignes sont des PID de processus en cours d'exécution, notez le “d” en début de ligne qui indique qu'il s'agit de répertoires (“directory”), voyons ce qui se trouve à l'intérieur pour le processus 5086.

$ ls -l /proc/5086
total 0
dr-xr-xr-x  2 tux tux 0  1 déc.  11:01 attr
-r--------  1 tux tux 0  1 déc.  11:01 auxv
-r--r--r--  1 tux tux 0  1 déc.  11:01 cgroup
--w-------  1 tux tux 0  1 déc.  11:01 clear_refs
-r--r--r--  1 tux tux 0  1 déc.  10:10 cmdline
-rw-r--r--  1 tux tux 0  1 déc.  11:01 comm
-rw-r--r--  1 tux tux 0  1 déc.  11:01 coredump_filter
-r--r--r--  1 tux tux 0  1 déc.  11:01 cpuset
lrwxrwxrwx  1 tux tux 0  1 déc.  11:01 cwd -> /home/tux/Documents
-r--------  1 tux tux 0  1 déc.  11:01 environ
lrwxrwxrwx  1 tux tux 0  1 déc.  10:48 exe -> /usr/lib/xulrunner-1.9.2/xulrunner-stub
dr-x------  2 tux tux 0  1 déc.  11:01 fd
dr-x------  2 tux tux 0  1 déc.  11:01 fdinfo
-r--r--r--  1 tux tux 0  1 déc.  11:01 limits
-rw-r--r--  1 tux tux 0  1 déc.  11:01 loginuid
-r--r--r--  1 tux tux 0  1 déc.  11:01 maps
-rw-------  1 tux tux 0  1 déc.  11:01 mem
-r--r--r--  1 tux tux 0  1 déc.  11:01 mountinfo
-r--r--r--  1 tux tux 0  1 déc.  11:01 mounts
-r--------  1 tux tux 0  1 déc.  11:01 mountstats
dr-xr-xr-x  5 tux tux 0  1 déc.  11:01 net
-r--r--r--  1 tux tux 0  1 déc.  11:01 numa_maps
-rw-r--r--  1 tux tux 0  1 déc.  10:10 oom_adj
-r--r--r--  1 tux tux 0  1 déc.  11:01 oom_score
-rw-r--r--  1 tux tux 0  1 déc.  11:01 oom_score_adj
-r--------  1 tux tux 0  1 déc.  11:01 pagemap
-r--------  1 tux tux 0  1 déc.  11:01 personality
lrwxrwxrwx  1 tux tux 0  1 déc.  11:01 root -> /
-r--r--r--  1 tux tux 0  1 déc.  11:01 sessionid
-r--r--r--  1 tux tux 0  1 déc.  11:01 smaps
-r--r--r--  1 tux tux 0  1 déc.  10:10 stat
-r--r--r--  1 tux tux 0  1 déc.  10:38 statm
-r--r--r--  1 tux tux 0  1 déc.  10:10 status
-r--------  1 tux tux 0  1 déc.  11:01 syscall
dr-xr-xr-x 12 tux tux 0  1 déc.  11:01 task
-r--r--r--  1 tux tux 0  1 déc.  11:01 wchan

Tous ces fichiers sont des interfaces vers des informations accessibles dans le noyau, ici ce qui nous intéresse c'est “maps” et “smaps”. La somme d'information étant très importante je ne montre ici qu'une fraction, faite un tour chez vous. Ici vous devriez deviner assez vite ce qui se cache derrière le processus 5086 :

$ cat /proc/5086/maps
[...]
00400000-00414000 r-xp 00000000 09:00 1048314           /usr/lib/xulrunner-1.9.2/xulrunner-stub
00614000-00615000 rw-p 00014000 09:00 1048314           /usr/lib/xulrunner-1.9.2/xulrunner-stub
7feab887d000-7feab923a000 r-xp 00000000 09:00 406303    /usr/lib/flashplayer-mozilla/libflashplayer.so
7feab923a000-7feab943a000 ---p 009bd000 09:00 406303    /usr/lib/flashplayer-mozilla/libflashplayer.so
7feab943a000-7feab9495000 rw-p 009bd000 09:00 406303    /usr/lib/flashplayer-mozilla/libflashplayer.so
7feabb0d8000-7feabb0fd000 r-xp 00000000 09:00 165473    /usr/lib/libaudiofile.so.0.0.2
7feabb0fd000-7feabb2fc000 ---p 00025000 09:00 165473    /usr/lib/libaudiofile.so.0.0.2
7feabb2fc000-7feabb300000 rw-p 00024000 09:00 165473    /usr/lib/libaudiofile.so.0.0.2
7feac7abd000-7feac7aca000 r-xp 00000000 09:00 824811    /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/amd64/libnpjp2.so
7feac7aca000-7feac7bc9000 ---p 0000d000 09:00 824811    /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/amd64/libnpjp2.so
7feac7bc9000-7feac7bcc000 rw-p 0000c000 09:00 824811    /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/amd64/libnpjp2.so
7feacc69b000-7feacc800000 r--p 00000000 09:02 25299858  /home/tux/.mozilla/firefox/eh36amhn.default/extensions/{D4DD63FA-}/downbarPackage.jar
7feacca0e000-7feaccc00000 r--p 00000000 09:00 139154    /usr/share/iceweasel/chrome/browser.jar
7feace19c000-7feace39c000 r--p 00000000 09:00 799404    /usr/share/xulrunner-1.9.2/chrome/toolkit.jar
7feace39c000-7feace500000 r--p 00000000 09:02 25690287  /home/tux/.mozilla/firefox/eh36amhn.default/extensions/{d1}/chrome/adblockplus.jar
[...]

Les plus geek d'entre vous auront reconnu derrière le processus 5086 le navigateur Internet Firefox dans sa version Debian (nommée "Iceweasel"). Les lignes commencent par les adresses de la plage de mémoire occupée par chaque élément, ce qui ne nous intéresse pas ici, mais surtout fournissent la quantité de mémoire (en octets) utilisée par chacun. C'est déjà nettement plus détaillé que ce que renvoie “top” au sujet d'un processus, mais on peut encore fouiller dans /proc/5086/smaps cette fois.

$ cat /proc/5086/smaps | less
[...]
7feab887d000-7feab923a000 r-xp 00000000 09:00 406303  /usr/lib/flashplayer-mozilla/libflashplayer.so
Size:               9972 kB
Rss:                 888 kB
Pss:                 444 kB
Shared_Clean:        888 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:          888 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
7feab923a000-7feab943a000 ---p 009bd000 09:00 406303  /usr/lib/flashplayer-mozilla/libflashplayer.so
Size:               2048 kB
Rss:                   0 kB
Pss:                   0 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:            0 kB
Swap:                  0 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB

Ici on a relayé le résultat vers le pager “less”, qui permet de lire confortablement la masse d'information. Pour rechercher un processus particulier dans “less” utilisez “/” suivi du motif de recherche pour rechercher en avant et “?” pour rechercher en arrière. “h” fera apparaître l'aide. Ici nous avons recherché “flash”, ce qui permet d'isoler la mémoire consommée par les processus liés à flashplayer au sein du navigateur Internet Firefox. Il y a plus d'informations que nécessaires, mais la ligne “size” vous donne une idée de la quantité de mémoire globale utilisée par le sous-processus (y compris la mémoire partagée), “rss” (“Resident Set Size”) est une valeur plus réaliste de la mémoire réellement utilisé, “pss” (proportional set size) évite de sur-représenter les gros consommateurs de mémoire partagée. La ligne “swap” vous indiquera si une partition “swap” (partition dédiée à suppléer la mémoire vive) est utilisée.

Vous me direz “c'est bien joli tout ça, mais comment je sais que le PID “5086” correspond à firefox ?”. Vous n'avez donc pas lu la page dédiée à la gestion des processus ? Courez-y !
Pour un cours de rattrapage on utilisera :

$ pgrep -l firefox
5086 firefox-bin

Maintenant que se passe-t-il si pgrep renvoi plusieurs processus, un exemple avec le navigateur Internet Chromium qui lance chaque onglet dans un sous-processus différent (une seule fenêtre de Chromium est ouverte) :

$ pgrep -l chromium
11435 chromium-browser
11437 chromium-browser
11439 chromium-browser
11457 chromium-browser
11461 chromium-browser
11463 chromium-browser
11467 chromium-browser
11471 chromium-browser
11477 chromium-browser
11480 chromium-browser
11483 chromium-browser
11486 chromium-browser
11491 chromium-browser
11502 chromium-browser
11526 chromium-browser
11529 chromium-browser
11536 chromium-browser
11541 chromium-browser
11584 chromium-browser
11590 chromium-browser
$ pstree -Ap

init(1)-+-Xprt(3154)
        |-acpid(2463)
        |-chromium-browse(10964)-+-chromium-browse(10983)---{chromium-brows}(10985)
        |                        |-chromium-browse(10986)---{chromium-brows}(10988)
        |                        |-chromium-browse(10989)---{chromium-brows}(10992)
        |                        |-chromium-browse(10993)---{chromium-brows}(10995)
        |                        |-chromium-browse(10998)---{chromium-brows}(11004)
        |                        |-chromium-browse(11006)---{chromium-brows}(11009)
        |                        |-chromium-browse(11010)---{chromium-brows}(11012)
        |                        |-chromium-browse(11013)---{chromium-brows}(11015)
        |                        |-chromium-browse(11021)---{chromium-brows}(11023)
        |                        |-chromium-browse(11027)---{chromium-brows}(11029)
        |                        |-chromium-browse(11046)---{chromium-brows}(11048)
        |                        |-chromium-browse(11052)---{chromium-brows}(11058)
        |                        `-chromium-browse(11062)---{chromium-brows}(11064)
[...]
        |-kdeinit4(3482)-+-chromium-browse(10960)-+-chromium-browse(10962)
        |                |                        |-chromium-browse(11026)-+-{chromium-brows}(11030)
        |                |                        |                        |-{chromium-brows}(11036)
        |                |                        |                        |-{chromium-brows}(11037)
        |                |                        |                        |-{chromium-brows}(11038)
        |                |                        |                        |-{chromium-brows}(11039)
        |                |                        |                        |-{chromium-brows}(11040)
        |                |                        |                        |-{chromium-brows}(11041)
        |                |                        |                        |-{chromium-brows}(11042)
        |                |                        |                        |-{chromium-brows}(11043)
        |                |                        |                        `-{chromium-brows}(11049)
        |                |                        |-chromium-browse(11077)---{chromium-brows}(11080)
        |                |                        |-{chromium-brows}(10969)
        |                |                        |-{chromium-brows}(10970)
        |                |                        |-{chromium-brows}(10971)
        |                |                        |-{chromium-brows}(10972)
        |                |                        |-{chromium-brows}(10973)
        |                |                        |-{chromium-brows}(10974)
        |                |                        |-{chromium-brows}(10975)
        |                |                        |-{chromium-brows}(10976)
        |                |                        |-{chromium-brows}(10978)
        |                |                        |-{chromium-brows}(10979)
        |                |                        |-{chromium-brows}(10996)
        |                |                        |-{chromium-brows}(10997)
        |                |                        |-{chromium-brows}(11016)
        |                |                        |-{chromium-brows}(11050)
        |                |                        |-{chromium-brows}(11051)
        |                |                        `-{chromium-brows}(11066)

Là, ça devient plus compliqué. Une solution peut être d'utiliser une commande un peu plus complexe du style :

$ for f in `pgrep chromium`; do cat /proc/$f/maps; done

Ça fonctionne, mais la somme d'information devient vite ingérable. On peut essayer de cibler en enchaînant sur une recherche avec grep ou egrep, mais la commande tourne vite à l'exercice de style, pas vraiment pratique à l'usage. Un exemple ciblant flashplayer et l'utilisation du cache par chromium.

$ for f in `pgrep chromium`; do cat /proc/$f/maps | egrep '(Cache|flashplayer)'; done

Heureusement pour mettre tout ça en forme il existe des outils plus adaptés.

memstat

Le fonctionnement de memstat n'a rien de compliqué, et il ne fait rien d'autre que récupérer, compiler et mettre en forme a minima les données accessibles dans /proc. Deux options sont pratiques, “-w” permet d'éviter le “line wrapping” (les lignes de résultat coupées à 80 caractères), “-p” permet de donner en argument un PID, sans cette option c'est l'ensemble de l'utilisation de la mémoire du système qui sera reportée :

$ pgrep -l firefox
5113 firefox-bin

$ memstat -wp 5113
 254648k: PID  5113 (/usr/lib/xulrunner-1.9.2/xulrunner-stub)
    384k(    384k): /SYSV00000000 5113
   2164k(    112k): /lib/libselinux.so.1 5113
   2304k(    248k): /lib/libdbus-1.so.3.4.0 5113
   2064k(     16k): /lib/libattr.so.1.1.0 5113
   2960k(    912k): /lib/libglib-2.0.so.0.2703.0 5113
   2064k(     16k): /lib/libuuid.so.1.3.0 5113
      4k(      4k): /var/cache/fontconfig/7ef2298fde41cc6eeb7af42e48b7d293-le64.cache-3 5113
   2076k(     28k): /lib/libacl.so.1.1.0 5113
   2240k(    192k): /lib/libpcre.so.3.12.1 5113
     76k(     76k): /var/cache/fontconfig/e13b20fdb08344e0e664864cc2ede53d-le64.cache-3 5113
[...]
   2652k(    592k): /usr/lib/libsqlite3.so.0.8.6 5113
    620k(      0k): /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf 5113
    572k(      0k): /usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf 5113
[...]
   1960k(    940k): /usr/lib/nvidia/libGL.so.195.36.31 5113
   2064k(     16k): /usr/lib/libcanberra-0.24/libcanberra-alsa.so 5113
   2072k(     20k): /usr/lib/gtk-2.0/modules/libcanberra-gtk-module.so 5113
   2108k(     56k): /usr/lib/gnome-vfs-2.0/modules/libfile.so 5113
  12384k(   9972k): /usr/lib/flashplayer-mozilla/libflashplayer.so 5113
    388k(      0k): /usr/share/xulrunner-1.9.2/chrome/classic.jar 5113
   2048k(      0k): /usr/share/xulrunner-1.9.2/chrome/toolkit.jar 5113
   1084k(     52k): /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/amd64/libnpjp2.so 5113
[...]
   2436k(    376k): /opt/google/talkplugin/libnpgoogletalk64.so 5113
     20k(     20k): /home/tux/.local/share/mime/mime.cache 5113
   1052k(      0k): /home/tux/.mozilla/firefox/eh36amhn.default/extensions/{53A03D43}/chrome/scrapbook.jar 5113
   1428k(      0k): /home/tux/.mozilla/firefox/eh36amhn.default/extensions/{D4DD63FA}/downbarPackage.jar 5113
    484k(      0k): /home/tux/.mozilla/firefox/eh36amhn.default/extensions/{b9db16a4}/chrome/dwhelper.jar 5113
   1424k(      0k): /home/tux/.mozilla/firefox/eh36amhn.default/extensions/{d10d0bf8}/chrome/adblockplus.jar 5113
     56k(      0k): /home/tux/.mozilla/firefox/eh36amhn.default/extensions/{EF522540}/chrome/googlepreview.jar 5113
   1600k(      0k): /home/tux/.mozilla/firefox/eh36amhn.default/extensions/{dc572301}/chrome/tabmixplus.jar 5113
--------
 655516k ( 101908k)

On combine maintenant une bonne lisibilité, un niveau de détail tout à fait adapté à notre usage. Pour chaque élément est indiqué la quantité de mémoire réservée, et entre parenthèses la quantité réellement utilisée par l'application. Gardez à l'esprit que memstat renvoie les chiffres de la mémoire virtuelle, pas ceux de la mémoire vive physique, ici on ne peut pas distinguer entre swap et ram. Mais pour une comparaison entre deux navigateurs Internet par exemple c'est amplement suffisant.

On peut organiser le résultat par quantité de mémoire utilisée décroissante en couplant avec “sort” :

$ pgrep -l chromium
32476 chromium-browser
32478 chromium-browser
32480 chromium-browser
32499 chromium-browser
32502 chromium-browser
[...]
 
$ memstat -wp 32476 | sort -tk -k1 -nr

533720k ( 129620k)
135160k: PID 32476 (/usr/lib/chromium-browser/chromium-browser)
41312k(  39160k): /usr/lib/chromium-browser/chromium-browser 32476
29188k(  28164k): /usr/lib/libGLcore.so.195.36.31 32476
16640k(      0k): /usr/lib/libicudata.so.44.2 32476
13568k(   8528k): /opt/google/talkplugin/lib/libCg.so 32476
12384k(   9972k): /usr/lib/flashplayer-mozilla/libflashplayer.so 32476
6268k(   4180k): /usr/lib/libgtk-x11-2.0.so.0.2000.1 32476
5444k(   5272k): /opt/google/talkplugin/libnpgtpo3dautoplugin.so 32476
3920k(   1824k): /usr/lib/libicui18n.so.44.2 32476
3440k(   1376k): /lib/libc-2.11.2.so 32476
3388k(   1304k): /usr/lib/libxml2.so.2.7.8 32476
3376k(   1264k): /usr/lib/libicuuc.so.44.2 32476
3308k(   1236k): /usr/lib/libX11.so.6.3.0 32476
2176k(    120k): /usr/lib/mozilla/plugins/libvlcplugin.so 32476
2164k(    112k): /lib/libselinux.so.1 32476
2148k(     96k): /usr/lib/libvlc.so.5.1.0 32476
[...]
1408k(    368k): /opt/google/talkplugin/lib/libCgGL.so 32476
1084k(     52k): /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/amd64/libnpjp2.so 32476
1032k(      4k): /usr/lib/tls/libnvidia-tls.so.195.36.31 32476
516k(    516k): /home/tux/.cache/chromium/Cache/index 32476
408k(    408k): /usr/lib/chromium-browser/resources.pak 32476
120k(    120k): /home/tux/.config/chromium/Default/Extensions/okmcbgkkeagngnijeiighgblfljbekip/2_0/Cached 32476
8k(      8k): /home/tux/.cache/chromium/Cache/data_0 32476
4k(      4k): /var/cache/fontconfig/107f8ab0c4468dd6985ac3fa3a150647-le64.cache-3 32476
--------
[...]

“sort” n'est pas notre sujet, mais sachez que l'option “-t” permet d'indiquer un délimiteur de champs (ici on indique le “k” de kilobyte), l'option “-k” permet de choisir le champ qui sera pris en compte pour le classement (ici le premier), enfin “-n” indique à “sort” d'utiliser la valeur numérique littérale du champ, et “r” inverse l'ordre de classement (ordre croissant par défaut).

:!: Attention au comportement de memstat, si plusieurs PID sont renvoyés par “pgrep” seul le premier sera pris en compte, il faut donc identifier les PID d'abord pour les passer en argument à memstat plutôt que d'imbriquer une invocation de pgrep dont seul le premier résultat sera pris en compte.

smem

Pour analyser rapidement l'utilisation mémoire d'un programme smem est un outil idéal. En plus de reporter des valeurs véritablement significatives (la colonne “rss” pour “Resident Set Size” est sans doute la valeur la plus représentative) il prend en compte l'ensemble des processus appartenant au programme. C'est un gros avantage par rapport à un simple coup d'œil à “top” qui ne reportera que les processus à la plus grosse consommation de ressources à un moment donné.

$ smem -ntkP [c]hromium

PID User     Command                         Swap      USS      PSS      RSS 
32478 1000     /usr/lib/chromium-browser/c        0     1.0M     5.1M    15.9M 
32560 1000     /usr/lib/chromium-browser/c        0    14.6M    17.1M    31.5M 
32586 1000     /usr/lib/chromium-browser/c        0    16.1M    19.2M    38.4M 
32476 1000     /usr/lib/chromium-browser/c        0    48.3M    57.0M    85.1M 
-------------------------------------------------------------------------------
   97 1                                           0    80.1M    98.5M   171.0M
$ smem -ntkP [f]irefox

PID User     Command                         Swap      USS      PSS      RSS 
32754 1000     /usr/lib/iceweasel/firefox-        0   140.7M   145.4M   159.0M 
-------------------------------------------------------------------------------
   79 1                                           0   140.7M   145.4M   159.0M

Les habitués de la commande "ps" reconnaîtront l'astuce de notation qui consiste à encadrer le premier caractère du motif de recherche de crochet([f]irefox), cela permet d'éliminer le processus “smem” lui même du résultat. Pour le reste on voit ici quelques options utiles comme :

  • -n” qui permet d'obtenir l'identifiant numérique (userID) plutôt que son nom de login,
  • t” affiche le total des différentes colonnes en bas de tableau,
  • k” permet d'obtenir des valeurs numériques avec un suffixe explicite en Kilo octets, Mega octets, etc…
  • Enfin “P” (majuscule) permet d'indiquer un processus cible, par défaut c'est la consommation de mémoire de l'ensemble du système qui est rapportée.

Si vous couplez “smem” avec “watch” vous pourrez suivre en direct l'évolution de la consommation de mémoire vive par l'application, et l'impact de telle ou telle action :

$ watch "smem -ntkP [c]hromium"



Parmi les autres options intéressantes “-s” suivi d'un label de colonne du tableau permet de classer les processus (ordre croissant), “-r” aura le même effet mais en classant les processus par ordre décroissant. Enfin “-c” permet de choisir les colonnes qui seront affichées :

$ smem -ktP [c]inelerra -c "vss uss pss rss" -r rss
     VSS      USS      PSS      RSS 
  999.8M    62.2M    86.4M   179.6M 
  460.4M    30.9M    46.3M   124.0M 
  452.0M    19.4M    34.8M   112.5M 
  448.2M     2.6M    17.9M    95.6M 
  447.8M     2.1M    17.4M    95.1M 
  395.2M    88.0K    15.3M    92.2M 
------------------------------------
    3.1G   117.3M   218.2M   699.0M

Parmi les colonnes disponibles les plus intéressantes sont :

  • pid (identifiant de processus)
  • command commande associée au processus
  • user uid du propriétaire du processus
  • pss “proportional set size” (inclue la mémoire partagée)
  • rss “resident set size” (inclue la mémoire partagée)
  • uss mémoire consommée uniquement par le processus visé
  • vss “virtual set size” (mémoire virtuelle allouée totale)
  • swap quantité de mémoire “swap” utilisée (hors mémoire partagée)

L'option “-m” permet de visualiser l'ensemble des “mappings” (allocations) de mémoire,“anonymous”

$ smem -m -ktP [f]irefox -c "map uss pss rss" -r rss

Map                                           USS      PSS      RSS 
<anonymous>                                125.9M   125.9M   125.9M
/usr/lib/xulrunner-1.9.2/libxul.so           7.7M    10.6M    13.4M
/opt/google/talkplugin/lib/libCg.so          8.5M     8.5M     8.5M
/usr/lib/libGLcore.so.195.36.31              6.0M     7.6M    14.2M
/usr/lib/libmozjs.so.3d                      1.2M     1.2M     1.3M
/opt/google/talkplugin/libnpgtpo3dautopl     1.1M     1.1M     1.1M
/home/thveillon/.mozilla/firefox/eh36amh   848.0K   848.0K   848.0K
/usr/lib/flashplayer-mozilla/libflashpla   328.0K   772.0K     1.2M
/home/thveillon/.mozilla/firefox/eh36amh   772.0K   772.0K   772.0K
/usr/share/xulrunner-1.9.2/chrome/toolki   620.0K   620.0K   620.0K
/usr/lib/libgtk-x11-2.0.so.0.2000.1         44.0K   584.0K     1.8M
/usr/share/iceweasel/chrome/browser.jar    408.0K   408.0K   408.0K
[...]
/var/cache/fontconfig/6eb3985aa4124903f6        0        0    16.0K
/var/cache/fontconfig/4794a0821666d79190        0        0     4.0K
/var/cache/fontconfig/107f8ab0c4468dd698        0        0     4.0K
/var/cache/fontconfig/0dad82dbaa6c15cf08        0        0    16.0K
/usr/lib/gconv/gconv-modules.cache              0        0    28.0K
--------------------------------------------------------------------
190                                        157.1M   165.5M   186.9M

Si vous vous demandez qui est cet “anonymous” qui squatte tant de mémoire, rien à voir avec le célèbre groupe d'"Hacktivistes", il s'agit des pages de mémoire virtuelle qui ne sont pas liées à un fichier (“fd” pour “file descriptor” est nul).

smem sait également produire des diagrammes pour rendre compte de l'utilisation mémoire, pour cela il est nécessaire d'installer “python-matplotlib”. L'option --pie permet de créer un diagramme circulaire (“camembert”), elle sera suivi de la valeur de référence pour les noms des processus (pid (par défaut), name), et éventuellement l'option “-s permettant de classer par valeur (rss, pss (par défaut), vss,…etc).

$ smem --pie name -s rss

Avec l'option -P on peut filtrer pour isoler un ou plusieurs processus cibles. Si vous référez les diagrammes en barres utilisez l'option “--bar=”.

Liens


Retour à la page Expert

expert/analyser_usage_memoire_vive.txt · Dernière modification: 2014/05/09 18:56 (modification externe)