Wir kennen es alle, Zig GB Ram in Hardware verbaut und die Kiste swappt trotzdem. Da will man irgendwann wissen, wer/welcher Prozess dafür verantwortlich ist. Aber der Reihe nach:
Was ist „Swappen“ ?
Dazu müssen wir erstmal wissen, was virtuelles Ram ist. Physikalisches Ram kann sich sicher jeder vorstellen, das kann man als Baustein in die Hand nehmen 😉 Selbiges ist z.b. 10 GB groß ( siehe unten / nicht fragen ist ne VM )
top - 16:26:05 up 17:16, 1 user, load average: 0,75, 0,56, 0,53
Tasks: 413 total, 1 running, 411 sleeping, 0 stopped, 1 zombie
%Cpu(s): 8,3 us, 4,0 sy, 0,0 ni, 86,5 id, 0,4 wa, 0,4 hi, 0,1 si, 0,2 st
KiB Mem : 10264728 total, 563348 free, 3256528 used, 6444852 buff/cache
KiB Swap: 1048572 total, 739584 free, 308988 used. 6788296 avail Mem
d.b. „physikalisch“ stehen allen Programmen zusammen maximal 10 GB Hauptspeicher zur Verfügung, mit dem sie auskommen müssen. Wenn alle RAM Speicherzellen benutzt werden und jemand will mehr Speicher haben, gibt es einen OOM Error : Out Of Memory! und die Aktion schlägt fehl, was Programme üblicherweise übel nehmen und die weitere Zusammenarbeit verweigern. Soweit, so klar.
Jetzt gibt es aber Programmierer, die mehr Speicher anfordern, als ihre Anwendung braucht. Der RAM wird „nutzlos“ belegt und steht anderen Programmen nicht zur Verfügung. Entweder müßte man GB weise Ram nachrüsten, oder man tut nur so als wenn man Speicher hätte 🙂
Virtueller Speicher
Auch VMEM genannt, ist nichts anderes als die Illusion, daß man mehr Speicher hat, als man hat. Technisch gesehen ist, das einfach: Bevor ein Programm nichts in den Speicher, den es anforderte, geschrieben hat, muß es den Speicher nicht wirklich geben. Man kann dem Programm einfach sagen, daß seine Anforderung nach 10 TB Ram erfolgreich war. Solange es die 10 TB nie benutzt, ist alles ok.
Wird von dem Programm etwas in seinen Speicherbereich geschrieben, so merkt dies das OS und kann den Speicherblock tatsächlich physikalisch machen. Eine MMU ( Memory Management Unit ) in der CPU macht das. Die mapped nämlich den echten Physikalischen Speicherbereich in den Virtuellen Speicherbereich, so daß die Schreibzugriffe an Adressen gehen, die es nicht wirklich gibt, aber so umgebogen werden, daß sie an der richtigen Stelle landen, alles hardwaremäßig.
Das klappt solange, wie der real genutzte Speicher kleiner ist, als die Menge verbauten Hauptspeichers.
Der Notfall: Einen OOM verhindern.
Kurz vor dem Punkt, wo das System keinen Speicher mehr hätte, wird geprüft, wann einzelne Speicherbereiche das letzte mal gelesen oder geschrieben wurden. Wenig verwundernd stellt man dann fest, daß es Speicherblöcke gibt, die in letzter Zeit nicht benutzt wurden.
Idee: Die könnte ich doch irgendwo in einem langsamen Speichermedium mit viel Platz auslagern, oder ? Gedacht, getan: Das Swappen wurde aktiviert und meint, daß bei Speichermangel ungenutzte Teile auf die Festplatte geschrieben werden und andere Teile, die dort schon lagen, wieder eingelesen werden. Man tauscht(swap) also die aktiven und inaktiven Speicherbereiche mit Hilfe der Platte aus.
Swappen
Dieser Vorgang heißt „swappen“. Es wird also ständig auf die Platte geschrieben und davon gelesen. Das hört sich erstmal nicht nach einem Problem an. Ist es aber, weil wenn soviel verschiedenes RAM ständig geswappt wird, wird das System langsam, schliesslich muß man warten bis dieser Vorgang vorbei ist. Wenn es langsam wird, stauen sich die Prozess: Die Load/Last steigt.
Die Idee beim Swapspeicher ist, daß man lange ungenutzte Speicherblöcke auslagert und die auch nicht gleich wieder benutzt werden. Auf einem Desktoprechner ist der Klassiker, daß der Speicher frei ist, bis Photoshop ein 50MP Bild lädt. Das geht vielleicht noch ins RAM, aber Browser, Mailprogramm, Kalender usw. nicht mehr. Da man aber gerade mit Photoshop arbeitet, ist das auch nicht schlimm, denn es ist nicht zu erwarten, daß ich vor Beendigung der aktiven Aufgabe von Photoshop eins der anderen Programme brauche. I.d.R. klappt das auch. Das führt zur irrigen Annahme, daß viel Swapspeicher = „total geile Sache“ ist.
Auf einem Server ist das etwas anderes. Da kann man nicht wirklich vorhersehen, wann ein Dienst gebraucht wird und da ist swappen zu vermeiden. Weil wenn viel Swapspeicher vorhanden ist, dauert es auch entsprechend lange, bis der voll beschrieben oder gelesen ist. d.h. der Rechner steht praktisch, nur weil er Speicher auf die Platte schreibt.
Auf einem Server ist es deutlich cleverer, wenig Swapspeicher zu haben, damit tatsächlich ein OOM entsteht, wenn es nötig ist. Kleinere temporäre Swaps sollten aber möglich bleiben. Deswegen ist der Swapspeicher im Beispiel oben auch nur 1 GB groß. Die Regel, daß der Swap 50% vom Hauptspeicher groß sein sollte, war im MB Bereich charmant, mit GB aber nicht mehr ganz so gut.
Wie verhindert man das Swappen ?
Mal davon abgesehen, daß man das Abschalten und auch das Verhalten des Swappens im Kernel beeinflussen kann, wäre es viel cleverer den Grund für das Swappen zu finden und das geht nur, wenn man weiß wer gerade geswappt wird.
Bevor die Kommentare losgehen: Das Programm, dessen Speicher auf dem Swapspeicher landet, muß nicht jenes sein, daß zuviel RAM wollte. Aber es ist das Programm auf das man am ehesten verzichten kann 😉 Das es überhaupt im Swap gelandet ist, beweist, daß es nicht aktiv war/ist und deswegen müßte man mal nachdenken, ob man es überhaupt braucht. Dazu muß man aber erstmal wissen, wer da gelandet ist.
SMEM – die Speicheranzeige
SMEM ist ein Tool, daß man sich per DNF nachinstallieren muß. Es produziert so eine Map :
PID User Command Swap USS PSS RSS
557 root /sbin/rngd -f 156 4 7 1292
752 root /sbin/agetty --noclear tty1 128 4 12 1692
753 root /sbin/agetty --keep-baud 11 152 4 35 2184
1690 mailman /usr/bin/python /usr/lib/ma 30000 4 51 1676
614 root /usr/sbin/atd -f 180 52 66 2104
18675 root sleep 60 0 80 97 1312
19506 root sleep 30s 0 84 126 1736
1467 samba /usr/sbin/smbd 2048 16 323 2868
9514 50779 dovecot/imap 0 312 340 3828
1659 nobody proftpd: (accepting connect 2076 144 349 2148
12494 root dovecot/log 0 348 355 2544
In der Liste kann man schön sehen, daß Mailman schön hervor sticht. Mailman ist ein Mailinglistenmanager. Den braucht man nur ganz selten. Da müßte man mal über einen Umzug nachdenken. Die Liste oben ist natürlich nur ein Auszug und wenig aussagekräftig. Im weiteren Verlauf tauchte Mailman dann entsprechend oft auf.
Hinweis: DAS ein Programm mal den einen oder anderen Block ausgelagert bekommen hat, ist nicht weiter dramatisch. Das gibts öfter und ist auch kein Problem, weil diese Teile üblicherweise nur beim Start wichtig waren und später einfach nicht mehr benutzt werden.
Wenn man den Verursacher des Speicherverbrauchs sucht, geht man anders vor:
watch -n 1 „top -c -b -n >> /tmp/memory.log“ oder watch -n 1 „smem >> /tmp/memory.log“
Wobei im Einzelfall „-n 1“ vielleicht ein bisschen zu oft ist und man jede Menge ungewollte IO generiert. Da müßt Ihr etwas auf Eure Bedürfnisse achten.
Aus der Ausgabe kann man dann mit AWK den Namen des Programms, den Speicherverbrauch und den Zeitpunkt ermitteln. Ein bisschen Bashmagie und man bekommt schnell mit, wer der Verursacher ist.
Kleines Beispiel auf dem Weg zum eigenen Terminal :
# smem | grep -E " [0-9]{6,} "
3983 root spamd chil 0 42344 47397 104600
8016 root spamd chil 0 44636 49667 106744
3937 root spamd chil 0 44924 49907 106584
4158 root spamd chil 0 45352 50354 107176
2033 exim /usr/sbin/clamd -c /etc/cla 772 497848 498045 501436
14335 mysql /usr/libexec/mysqld --based 0 853144 853421 858820
4269 nobody java server/Server 0 1175172 1175819 1179580
Das gibt einem nur die Zeilen aus, in denen mehr als fünfstellige Zahlen vorkommen, weil den Kleinkram suchen wir ja nicht.
In dem Beispiel oben lohnt sich der Blick auf den Clam AntiVirusprozess clamd. Der verbraucht mittlerweile 750MB RAM nur durch den Start und der größte Block davon ist meistens unbenutzt. Clamd bietet sich als Ziel der Aktion auch deswegen an, weil er netzwerkfähig ist. Man kann also leicht einen zweiten Server aufbauen, der nur Clamd laufen hat und zu dem alle anderen Server hingehen und Ihre Mails auf Viren checken lassen.
So bräuchte man die 750 MB nicht mehr auf jedem Mailserver verbraten, sondern nur einmal. Natürlich setzt das voraus, daß der Server mit dem Clamd auch schnell etwaige Anfragen beantwortet. Aber das ist ein anderes Thema.