Wie man rausbekommt, wer ausgeswappt wurde

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, daß 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 mappt 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 Hauptspeicher.

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.

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 grade 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 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 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 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 beeinflußen kann, wäre es viel cleverer den Grund für das Swappen zu finden und das geht nur, wenn man weiß er geswappt ist.

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.

Schreibe einen Kommentar