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
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.
Ich kann ad-hoc keine schlüssige Begründung angeben, ich habe aber beim Entwickler nachgefragt. Wenn ich etwas höre, berichte ich hier. Meine Vermutungen gehen in diese Richtung:
http://serverfault.com/questions/647645/ps-mem-py-vs-top-memory-usage
http://wiki.apache.org/spamassassin/TopSharedMemoryBug
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
liefertsudo smem -tk --columns='command uss'
tatsächlich ganz ähnliche Ergebnisse wieps_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 gibtslabtop
.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?