LinuxPedia

Wiki libre et indépendant dédié à GNU-Linux et BSD.

Outils pour utilisateurs

Outils du site


expert:analyser_usage_memoire_vive
no way to compare when less than two revisions

Différences

Ci-dessous, les différences entre deux révisions de la page.


expert:analyser_usage_memoire_vive [2018/11/17 12:53] (Version actuelle) – créée - modification externe 127.0.0.1
Ligne 1: Ligne 1:
 +=====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 [[gnome:evolution:|Evolution]] vs [[internet:thunderbird:|Thunderbird]], [[multimedia:amarok:|Amarok]] vs [[multimedia:rhythmbox:]] vs [[multimedia:banshee:]] ou comme c'est la mode en ce moment [[internet:firefox:|Firefox]] vs [[internet:chromium:|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 [[commande:job_control:|"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 [[commande:job_control:|top]] et [[commande:htop_atop:|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 [[kde:ksysguard:|"ksysguard"]] de [[kde:kde4:|KDE]]. Pratique quand on a une interface graphique et un environnement de bureau installé :\\
 +
 +{{ :expert:ksysguard1.png?direct&300 |}}
 +
 +====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 :
 +
 +<code>$ ls -l /proc
 +[...]
 +dr-xr-xr-x  7 tux  tux                0  1 déc.  10:10 5086
 +dr-xr-xr-x  7 root root                1 déc.  09:10 559
 +dr-xr-xr-x  7 root root                1 déc.  09:10 561
 +dr-xr-xr-x  7 root root                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
 +</code>
 +
 +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.
 +
 +<code>$ 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
 +</code>
 +
 +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 :
 +
 +<code>$ 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
 +[...]</code>
 +
 +Les plus geek d'entre vous auront reconnu derrière le processus 5086 le navigateur Internet Firefox dans sa version Debian (nommée [[internet:iceweasel:|"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.
 +
 +<code>$ 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
 +</code>
 +
 +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 à [[le_plugin_flash:|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 [[commande:job_control| la page dédiée à la gestion des processus]] ? Courez-y !\\
 +Pour un cours de rattrapage on utilisera :
 +
 +<code>$ pgrep -l firefox
 +5086 firefox-bin
 +</code>
 +
 +Maintenant que se passe-t-il si **pgrep** renvoi plusieurs processus, un exemple avec le navigateur Internet [[internet:chromium|Chromium]] qui lance chaque onglet dans un sous-processus différent (une seule fenêtre de Chromium est ouverte) :
 +
 +<code>$ 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
 +</code>
 +
 +<code>$ 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)
 +</code>
 +
 +Là, ça devient plus compliqué. Une solution peut être d'utiliser une commande un peu plus complexe du style :
 +
 +<code>$ for f in `pgrep chromium`; do cat /proc/$f/maps; done</code>
 +
 +Ça fonctionne, mais la somme d'information devient vite ingérable. On peut essayer de cibler en enchaînant sur une recherche avec [[commande:grep_egrep:|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.
 +
 +<code>$ for f in `pgrep chromium`; do cat /proc/$f/maps | egrep '(Cache|flashplayer)'; done</code>
 +
 +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 :
 +
 +<code>$ 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)</code>
 + 
 +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" :\\
 + 
 +<code>$ 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
 +--------
 +[...]</code>
 +
 +"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é.
 +
 +<code>$ smem -ntkP [c]hromium
 +
 +PID User     Command                         Swap      USS      PSS      RSS 
 +32478 1000     /usr/lib/chromium-browser/       0     1.0M     5.1M    15.9M 
 +32560 1000     /usr/lib/chromium-browser/       0    14.6M    17.1M    31.5M 
 +32586 1000     /usr/lib/chromium-browser/       0    16.1M    19.2M    38.4M 
 +32476 1000     /usr/lib/chromium-browser/       0    48.3M    57.0M    85.1M 
 +-------------------------------------------------------------------------------
 +   97 1                                              80.1M    98.5M   171.0M
 +</code>
 +
 +<code>$ 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                                             140.7M   145.4M   159.0M
 +</code>
 +
 +Les habitués de [[commande:job_control:|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 :\\
 +
 +<code>$ watch "smem -ntkP [c]hromium"</code>
 +\\
 +\\
 +
 +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 :
 +
 +<code>$ 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
 +</code>
 +
 +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"
 +
 +
 +<code>$ 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
 +</code>
 +
 +Si vous vous demandez qui est cet "anonymous" qui squatte tant de mémoire, rien à voir avec le célèbre [[https://secure.wikimedia.org/wikipedia/fr/wiki/Anonymous_%28communaut%C3%A9%29|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).\\
 +
 +<code>$ smem --pie name -s rss</code>
 +
 +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=**".\\
 +
 +{{ :expert:smem_rss.jpeg?direct&300 |}}
 +
 +====Liens====
 +  * [[http://fullcircle-mag.fr/index.php?pages/publications|Magazine "Full Circle" n°39]], cherchez l'article "Comprenez les stat[istiques] de la mémoire virtuelle".
 +
 +  * [[http://www.selenic.com/smem/|Site officiel]]
 +
 +  * [[http://linux.about.com/library/cmd/blcmdl2_mmap.htm|mmap ("memory mapping")]]
 +
 +  * [[https://secure.wikimedia.org/wikipedia/en/wiki/Mmap|"mmap et anonymous memory"]]
 +
 +----------------
 +
 +[[expert:|Retour à la page Expert]]
expert/analyser_usage_memoire_vive.txt · Dernière modification : 2018/11/17 12:53 de 127.0.0.1