Linux-Speichernutzung mit ps_mem ergründen

Gerade bin ich über ein ebenso nützliches wie empfehlenswertes Python-Script gestolpert: ps_mem hilft dabei, die Speichernutzung auf einem Linux-System nach Programmen aufzuschlüsseln. Im Gegensatz zu top oder ps zählt ps_mem nicht jeden Prozess einzeln auf. Außerdem bemüht sich das Programm so gut wie möglich, gemeinsam genutzte Bibliotheken herauszurechnen (shared memory). Und schließlich wird das Ergebnis in einer wirklich lesbaren Form präsentiert.

Der Python-Code und die Dokumentation des Scripts befinden sich auf github:

https://github.com/pixelb/ps_mem/

Nach dem Download können Sie das Script direkt ausführen. Das Script erfordert allerdings root-Rechte, d.h. Sie müssen dem Entwickler Pádraig Brady einiges Vertrauen entgegenbringen. Dessen Anstellung bei Red Hat ist da sicher hilfreich :-)

Beispiel 1 (Webserver)

Die Nutzung des Kommandos ist nahezu selbsterklärend. Die folgenden Zeilen sind auf einem Webserver unter Ubuntu 14.04 für eine stark datenbank-orientierte Web-Applikation entstanden.

python ps_mem.py 
 Private  +   Shared  =  RAM used   Program

 72.0 KiB +  20.0 KiB =  92.0 KiB   logger
 60.0 KiB +  35.5 KiB =  95.5 KiB   acpid
148.0 KiB +  39.5 KiB = 187.5 KiB   anvil
124.0 KiB +  68.0 KiB = 192.0 KiB   cron
140.0 KiB +  63.5 KiB = 203.5 KiB   upstart-socket-bridge
176.0 KiB +  31.5 KiB = 207.5 KiB   mdadm
148.0 KiB +  64.0 KiB = 212.0 KiB   upstart-file-bridge
  4.0 KiB + 227.0 KiB = 231.0 KiB   mysqld_safe
192.0 KiB +  49.0 KiB = 241.0 KiB   irqbalance
204.0 KiB +  44.5 KiB = 248.5 KiB   log
236.0 KiB +  29.5 KiB = 265.5 KiB   smartd
 36.0 KiB + 249.0 KiB = 285.0 KiB   getty (6)
216.0 KiB +  76.5 KiB = 292.5 KiB   systemd-udevd
148.0 KiB + 153.5 KiB = 301.5 KiB   master
240.0 KiB +  69.0 KiB = 309.0 KiB   dovecot
244.0 KiB +  93.0 KiB = 337.0 KiB   upstart-udev-bridge
300.0 KiB + 154.5 KiB = 454.5 KiB   pickup
388.0 KiB + 172.5 KiB = 560.5 KiB   qmgr
460.0 KiB + 102.5 KiB = 562.5 KiB   ntpd
412.0 KiB + 152.5 KiB = 564.5 KiB   systemd-logind
560.0 KiB +  54.5 KiB = 614.5 KiB   dbus-daemon
  1.1 MiB +  59.0 KiB =   1.1 MiB   config
960.0 KiB + 218.0 KiB =   1.2 MiB   tlsmgr
  1.0 MiB + 197.5 KiB =   1.2 MiB   sudo
  1.2 MiB + 121.5 KiB =   1.3 MiB   init
820.0 KiB +   2.0 MiB =   2.8 MiB   sshd (3)
  4.3 MiB + 840.0 KiB =   5.1 MiB   bash (2)
  4.5 MiB +   1.0 MiB =   5.6 MiB   imap-login (7)
  5.1 MiB + 776.5 KiB =   5.8 MiB   fail2ban-server
  5.2 MiB +   1.3 MiB =   6.5 MiB   imap (7)
 17.0 MiB +  60.5 KiB =  17.0 MiB   rsyslogd
 66.3 MiB +  24.2 MiB =  90.5 MiB   apache2 (11)
742.7 MiB + 194.5 KiB = 742.9 MiB   mysqld
---------------------------------
                        887.3 MiB
=================================

Ergänzend das Ergebnis von free und top:

free -h
             total  used  free  shared buffers  cached
Mem:           31G   30G  325M     23M    167M     28G
-/+ buffers/cache:  2.0G   29G
Swap:          15G   82M   15G
top - 22:04:56 up 52 days, 16:21,  1 user,  load average: 0.00, 0.01, 0.05
Tasks: 177 total,   1 running, 176 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.2 us,  0.0 sy,  0.0 ni, 99.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
28003 www-data  20   0  360300  30048  18572 S   0.7  0.1   0:00.55 apache2
 1898 mysql     20   0 1357500 761528  10224 S   0.3  2.3  61:57.13 mysqld
28094 www-data  20   0  360328  29200  17632 S   0.3  0.1   0:00.63 apache2
28151 www-data  20   0  357580  13144   4932 S   0.3  0.0   0:00.23 apache2
28259 www-data  20   0  366772  36320  20180 S   0.3  0.1   0:00.38 apache2
    1 root      20   0   33372   2392   1460 S   0.0  0.0   0:03.21 init
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.05 kthreadd
    3 root      20   0       0      0      0 S   0.0  0.0   0:10.10 ksoftirqd/0

Beispiel 2 (Desktop-System)

Das folgende Ergebnis ist auf einem Desktop-System entstanden (openSUSE 13.2 mit KDE im Leerlauf, in einer VirtualBox-Machine).

Private  +   Shared  =  RAM used    Program

  4.0 KiB +  32.5 KiB =  36.5 KiB   lvmetad
  4.0 KiB +  43.5 KiB =  47.5 KiB   wpa_supplicant
 20.0 KiB +  45.0 KiB =  65.0 KiB   wickedd-nanny
 56.0 KiB +  19.0 KiB =  75.0 KiB   haveged
  4.0 KiB +  82.5 KiB =  86.5 KiB   cupsd
 52.0 KiB +  36.0 KiB =  88.0 KiB   dmeventd
 72.0 KiB +  30.5 KiB = 102.5 KiB   atd
      ...
  7.5 MiB +   2.6 MiB =  10.1 MiB   systemd-journald
  6.2 MiB +   4.4 MiB =  10.6 MiB   konsole
 11.0 MiB + 232.5 KiB =  11.3 MiB   polkitd
  7.1 MiB +   5.1 MiB =  12.2 MiB   kmix
 15.8 MiB +   5.8 MiB =  21.6 MiB   krunner
 21.9 MiB +   8.6 MiB =  30.5 MiB   kwin
 41.1 MiB +   5.8 MiB =  46.9 MiB   kded4
 79.3 MiB +   7.8 MiB =  87.0 MiB   Xorg
114.7 MiB +  16.0 MiB = 130.6 MiB   plasma-desktop
---------------------------------
                        483.9 MiB
=================================

Auch hier free als Vergleichsmaßstab:

free -h
             total   used   free  shared  buffers  cached
Mem:          1.1G   1.0G    93M     15M       8K    671M
-/+ buffers/cache:   390M   764M
Swap:         1.7G    23M   1.7G

4 Gedanken zu „Linux-Speichernutzung mit ps_mem ergründen“

  1. Wie kommt es zu den Differenzen bei der Ausgabe zwischen free und ps_mem?

    Im ersten Beispiel werden laut „ps_mem“ ca. 890 MB, laut „free“ aber ca. 2 GB verwendet.

    Für eine Erklärung wäre ich dankbar.

    1. Pádraig Brady hat mir gerade die folgende Erklärung gesendet:

      ps_mem only accounts for mem used directly by processes.
      Any other mem used by the kernel is not accounted for.
      So it seems your kernel is using about 1.2G
      That does seem large but not beyond possibility.
      You might like to verify with a similar tool like:

      smem -tk –columns=’command uss‘

      Nach apt-get install smem --no-install-recommends liefert sudo smem -tk --columns='command uss' tatsächlich ganz ähnliche Ergebnisse wie ps_mem.

      Und das führt uns auch schon zum nächsten Tool zur Analyse des genutzten Speichers …

      http://www.selenic.com/smem/

      Und zum Thema, wie viel Speicher der Kernel beansprucht, gibt es hier interessante Infos:

      http://unix.stackexchange.com/questions/97261/how-much-ram-does-the-kernel-use

      grep Slab /proc/meminfo offenbart auf dem Testrechner tatsächlich mehr als ein GByte Kernel-Speicher. Mehr Details gibt slabtop.

  2. Danke für das Nachhaken, Herr Kofler. „smem“ ist auch sehr interessant (ebenso wie die Diskussion zum Kernel-Memory).

    Letztlich scheint es aber auf den ersten Blick irgendwie dennoch so, dass „free“ hier die verlässlicheren Ergebnisse liefert. Denn ich will ja wissen wie viel RAM insgesamt in Nutzung ist – bzw. wie viel RAM ich noch verwenden kann. Ob das RAM nun vom Kernel oder von den (User-)Prozessen belegt wird finde ich jetzt nicht so relevant.

    Da die zweite Zeile bei „free“ ja bereits Buffer und Cache beinhaltet bzw. abzieht verstehe ich es so, dass der Filesystem Cache (welcher in der Kernel Memory Diskussion aufgeführt wird) bereits berücksichtigt wird. Vielleicht verstehe ich das auch falsch.

    Bisher habe ich die Erklärung von http://www.linuxatemyram.com/ immer für bare Münze gehalten und meinen Vorgesetzten gezeigt, wenn man mal wieder ein Nagios-Alarm kam, weil „diese verdammten Linux-Server wieder das RAM fressen“ – es ist schon schwierig genug meinem Chef zu erklären, dass unsere Nagios-RAM-Überwachung der Linux-Systeme wie wir die aktuell machen Unsinn ist. Ich hatte gehofft hier vielleicht mal einen Ansatz zu finden, wie man diese sinnvoller durchführen könnte.

    Jetzt bin ich jedenfalls irgendwie noch verwirrter als vorher – wie viel RAM ist denn nun noch *wirklich* verfügbar bzw. wie viel belegt?

Kommentare sind geschlossen.