Swap einrichten und Abstürze durch Speichermangel verhindern

Veröffentlicht am 15 Min. Lesezeit

Dienst weg, kein Absturzbericht, Logfile endet mitten im Satz: So weisen Sie einen OOM-Kill nach, legen eine Swap-Datei sauber an und erkennen, wann Swap das Problem nur verschiebt.

Der Dienst ist weg. Kein Absturzbericht, kein Stacktrace, das Logfile endet mitten in einer Zeile. MariaDB antwortet nicht mehr, nginx liefert 502, der Minecraft-Server ist offline, und in der Anwendung selbst steht nichts Auffälliges. Das ist fast immer dasselbe Muster: Der Kernel hatte keinen freien Speicher mehr und hat einen Prozess beendet, um das System am Leben zu halten. Dieser Artikel zeigt, wie Sie das zweifelsfrei nachweisen, wie Sie eine Swap-Datei sauber anlegen und dauerhaft eintragen, und in welchen Fällen Swap das Problem nur um ein paar Minuten verschiebt.

Beweis führen: dmesg und journalctl

Bevor irgendetwas eingerichtet wird, brauchen Sie den Nachweis. Der Kernel schreibt bei jedem OOM-Kill (Out of Memory) einen ausführlichen Block in den Ring-Puffer:

dmesg -T | grep -iE 'out of memory|oom-kill'

Kommt keine Zeile zurück und der Befehl endet mit Exit-Code 1, gab es seit dem letzten Systemstart keinen Kernel-OOM. Der Exit-Code ist dabei kein Fehler, sondern nur die übliche Rückmeldung von grep ohne Treffer. Kommt etwas zurück, sieht es auf allen vier hier behandelten Systemen so aus:

mariadbd invoked oom-killer: gfp_mask=0x140cca(GFP_HIGHUSER_MOVABLE|__GFP_COMP), order=0, oom_score_adj=0
oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/system.slice/mariadb.service,task=mariadbd,pid=1043,uid=107
Out of memory: Killed process 1043 (mariadbd) total-vm:2894760kB, anon-rss:1583204kB, file-rss:0kB, shmem-rss:0kB, UID:107 pgtables:3820kB oom_score_adj:0

Drei Dinge daran sind wichtig. Erstens: invoked oom-killer nennt den Prozess, der die Speicheranforderung gestellt hat, nicht zwingend den Schuldigen. Zweitens: Der getötete Prozess steht in der Zeile Killed process. Drittens: Maßgeblich ist anon-rss, also der tatsächlich belegte anonyme Speicher. total-vm ist reservierter Adressraum und bei Java oder Go regelmäßig ein Vielfaches davon, das sagt nichts aus.

Läuft dmesg ohne root, quittiert es auf Debian 12, Debian 13, Ubuntu 22.04 und Ubuntu 24.04 mit dmesg: read kernel buffer failed: Operation not permitted, weil kernel.dmesg_restrict überall auf 1 steht. Also mit sudo arbeiten oder als root. Bleibt die Meldung auch als root stehen, sitzen Sie in einem LXC- oder OpenVZ-Container, der keinen Zugriff auf den Ring-Puffer des Wirtssystems hat. Dann führt nur der zweite Weg über journalctl -k weiter.

Der Ring-Puffer ist nach einem Neustart leer. Deshalb der zweite Weg über das Journal, und hier steckt die Falle, an der die meisten Anleitungen vorbeigehen:

journalctl -k --grep "Out of memory"

-k impliziert -b, zeigt also ausschließlich den aktuellen Bootvorgang. Wenn die Kiste nach dem Vorfall neu gestartet ist, liefert dieser Befehl nichts, obwohl das Ereignis protokolliert wurde. Für den vorherigen Start beziehungsweise für einen Zeitraum:

journalctl -k -b -1 --grep "Out of memory"
journalctl --since "7 days ago" --grep "Out of memory|oom-kill"

Antwortet der erste der beiden Befehle mit No journal boot entry found for the specified boot (-1), ist im Journal schlicht kein früherer Bootvorgang gespeichert. Auch das ist kein Fehler, sondern der Normalfall auf einem System, dessen Journal erst seit dem aktuellen Start mitschreibt.

Das funktioniert nur, wenn das Journal überhaupt persistent ist. Prüfen Sie das:

ls -d /var/log/journal

Auf Debian und Ubuntu ist dieses Verzeichnis ab Werk vorhanden, der Test liefert also fast immer einen Treffer und das folgende mkdir ist dann ein Leerlauf, der nichts kaputt macht. Existiert das Verzeichnis ausnahmsweise doch nicht, liegt das Journal nur in /run und ist nach jedem Neustart verloren. Das lässt sich in zwei Befehlen nachholen:

mkdir -p /var/log/journal
systemctl restart systemd-journald

Kernel-OOM oder systemd-Limit? Zwei verschiedene Ursachen

Diese Unterscheidung entscheidet darüber, ob Swap überhaupt etwas bringt. Achten Sie auf das Feld constraint in der Kernelmeldung.

CONSTRAINT_NONE bedeutet: Dem ganzen System ist der Speicher ausgegangen. Hier hilft Swap.

CONSTRAINT_MEMCG bedeutet: Nur eine einzelne Control-Group hat ihr Limit gerissen, das übrige System hatte reichlich Luft. Hier hilft Swap nicht, hier muss das Limit steigen oder die Anwendung sparsamer werden. Solche Kills erkennen Sie auch am Dienst selbst:

systemctl status mariadb

Steht dort Main process exited, code=killed, status=9/KILL und weiter unten Failed with result 'oom-kill', war es ein OOM-Kill. Ob ein cgroup-Limit im Spiel war, verrät eine Zählerdatei. Sie setzt cgroup v2 voraus, das auf allen vier Distributionen der Standard ist; unter dem älteren cgroup v1 existiert der Pfad nicht:

cat /sys/fs/cgroup/system.slice/mariadb.service/memory.events
systemctl show mariadb -p MemoryMax -p MemoryHigh

Ein Wert größer null bei oom_kill zusammen mit einem gesetzten MemoryMax ist der Beleg für ein lokales Limit.

Es gibt noch einen dritten Kandidaten, der oft übersehen wird, weil er gar nichts in dmesg schreibt: systemd-oomd. Der Dienst arbeitet im Userspace, wertet den Druckindikator PSI aus und beendet ganze Control-Groups, bevor der Kernel überhaupt eingreift. Seine Meldung im Journal lautet sinngemäß Killed /system.slice/... due to memory pressure for /system.slice being 60.00% > 50.00% for > 20s with reclaim activity. Prüfen Sie, ob er läuft:

systemctl is-active systemd-oomd

Auf Ubuntu ist systemd-oomd seit 22.04 ab Werk installiert und aktiv, auf Debian gehört er nicht zur Standardausstattung. Ein inactive auf einem Debian-Server ist also erwartbar und kein Hinweis auf einen Fehler.

Wichtig für später: systemd-oomd kann auch auslösen, weil der Swap voll läuft. Mehr Swap kann bei aktivem oomd die Abbrüche also sogar früher auslösen statt später.

Vor dem Swap: wie viel Speicher fehlt wirklich

Zwei Minuten Messen sparen eine falsche Entscheidung.

free -h

Interessant ist ausschließlich die Spalte available, nicht free. Cache zählt als verfügbar und wird bei Bedarf freigegeben. Wer die Spalte free liest, hält jedes gesunde System für überlastet.

ps -eo pid,comm,rss,%mem --sort=-rss | head -n 11
systemd-cgtop --order=memory -b -n 1

Die erste Zeile zeigt die größten Einzelprozesse, die zweite gruppiert nach Diensten. In der Praxis stehen dort fast immer dieselben drei Verdächtigen: MariaDB mit zu groß gewähltem innodb_buffer_pool_size, PHP-FPM mit zu hohem pm.max_children und eine JVM mit zu großzügigem -Xmx.

Als Ausgangsgröße für die Swap-Datei reicht diese Tabelle. Größer ist auf einem Server nicht besser, denn Swap, den Sie tatsächlich vollständig benutzen, macht die Maschine unbedienbar.

ArbeitsspeicherSinnvolle Swap-Datei
1 GB1 bis 2 GB
2 GB2 GB
4 bis 8 GB2 bis 4 GB
16 GB und mehr4 GB, selten mehr

Swap-Datei anlegen

Zuerst nachsehen, ob schon Swap existiert. Ubuntu-Server aus dem ISO-Installer bringen häufig bereits /swap.img mit, Debian aus dem Installer meist eine echte Swap-Partition. Cloud-Abbilder beider Distributionen haben in der Regel gar nichts.

swapon --show

Bleibt die Ausgabe leer, gibt es keinen Swap. Prüfen Sie als Nächstes das Dateisystem, denn davon hängt das Vorgehen ab:

findmnt -no FSTYPE -T /

Bei ext4 oder xfs geht es direkt weiter. Legen Sie die Datei mit dd an, nicht mit fallocate. fallocate ist schneller, erzeugt aber je nach Dateisystem und Kernel eine Datei mit nicht geschriebenen Bereichen, und swapon lehnt die dann ab. dd schreibt echte Nullen und funktioniert überall:

dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
chmod 600 /swapfile

Vor dem nächsten Schritt lohnt eine Kontrolle, die viele überspringen. Liegt unter /swapfile bereits ein eingeschalteter Swap, etwa aus einem früheren Versuch oder aus der Voreinstellung des Abbilds, verweigert mkswap die Arbeit mit mkswap: error: /swapfile is mounted; will not make swapspace. Maßgeblich ist dabei nur, ob der Pfad in /proc/swaps als aktiv geführt wird. Also nachsehen und gegebenenfalls abschalten:

swapon --show
swapoff /swapfile

Erscheint in swapon --show keine Zeile mit /swapfile, können Sie das swapoff überspringen. Danach den Auslagerungsbereich schreiben:

mkswap /swapfile

mkswap antwortet mit Setting up swapspace version 1, size = 2 GiB (2147479552 bytes) und einer neuen UUID. Erst danach einschalten:

swapon /swapfile

Die Reihenfolge ist nicht verhandelbar. chmod vor mkswap, mkswap vor swapon, und ein etwaiges swapoff vor allem anderen.

Woran Sie erkennen, dass es wirklich funktioniert hat

Dass swapon ohne Fehlermeldung durchläuft, ist noch kein Beweis. Diese beiden Ausgaben sind der Beweis:

swapon --show
free -h

swapon --show muss eine Zeile mit /swapfile, file, der Größe und einer Priorität ausgeben. In free -h muss die Zeile Swap: von 0B auf die neue Größe gesprungen sein. Bleibt eine der beiden Ausgaben unverändert, ist der Swap nicht aktiv, egal was der Befehl vorher gemeldet hat.

Dauerhaft eintragen, ohne den Boot zu riskieren

Ein swapon überlebt keinen Neustart. Der Eintrag gehört in /etc/fstab, und genau dort werden Server zerlegt. Erst sichern:

cp /etc/fstab /etc/fstab.bak
echo '/swapfile none swap sw 0 0' >> /etc/fstab

Achten Sie auf die zwei Größerzeichen. Ein einzelnes > überschreibt die gesamte Datei, und dann startet die Maschine nicht mehr sauber. Danach die Syntax prüfen, bevor Sie neu starten:

findmnt --verify

Eine Warnung ist dabei völlig normal und kein Grund, die Zeile wieder zu entfernen: [W] non-bind mount source /swapfile is a directory or regular file. Das ist bei einer Swap-Datei zwangsläufig so, der Befehl endet trotzdem mit Rückgabewert 0. Fehlt der Datei zusätzlich noch ein gültiger Swap-Kopf, kommt [W] cannot detect on-disk filesystem type dazu, und dann haben Sie tatsächlich ein mkswap vergessen.

Haben Sie den Swap oben bereits von Hand mit swapon /swapfile eingeschaltet, ist er jetzt schon aktiv. Wenn nicht, aktiviert swapon -a alle Einträge aus der fstab, ohne dass Sie neu starten müssen. Der eigentliche Test ist aber ein anderer. systemd erzeugt aus jeder fstab-Zeile eine eigene Unit, für /swapfile heißt sie swapfile.swap. Wenn diese Unit erscheint und aktiv ist, wird der Swap beim nächsten Start garantiert eingebunden:

systemctl daemon-reload
systemctl list-units --type swap

Erwartet wird eine Zeile swapfile.swap loaded active active Swap. Fehlt sie, stimmt die fstab-Zeile nicht, und ein Neustart würde ohne Swap enden. Erst wenn das passt, lohnt der Neustart mit anschließender Kontrolle über swapon --show.

swappiness richtig setzen

Der Kernelparameter vm.swappiness steuert, wie bereitwillig anonyme Seiten ausgelagert werden statt Dateicache zu verwerfen. Der Standard ist auf Debian 12, Debian 13, Ubuntu 22.04 und Ubuntu 24.04 identisch 60:

cat /proc/sys/vm/swappiness

Der Wertebereich geht seit Kernel 5.8 von 0 bis 200, alle vier Distributionen liegen darüber. Zwei verbreitete Irrtümer: vm.swappiness=0 schaltet Swap nicht ab, es verhindert nur das vorsorgliche Auslagern und lässt den Kernel trotzdem in die Auslagerung gehen, bevor er tötet. Und ein niedriger Wert macht ein System nicht schneller, wenn der Speicher schlicht fehlt.

Sinnvolle Werte: 10 bis 20 auf Datenbankservern, 60 auf gemischten Webservern, 100 und mehr, wenn Sie zram einsetzen. Dauerhaft gehört das in eine eigene Datei unter /etc/sysctl.d/, nicht in die /etc/sysctl.conf, die bei Paketaktualisierungen im Weg steht:

echo 'vm.swappiness = 10' > /etc/sysctl.d/99-swappiness.conf
sysctl --system
cat /proc/sys/vm/swappiness

Der dritte Befehl ist die Erfolgskontrolle. sysctl --system liest alle Verzeichnisse in fester Reihenfolge, und eine bereits vorhandene Datei mit höherer Nummer kann Ihren Wert überschreiben.

Wenn es schiefgeht: die Fehlermeldungen im Wortlaut

swapon: /swapfile: insecure permissions 0644, 0600 suggested. Nur eine Warnung, der Swap läuft trotzdem. Trotzdem beheben, sonst kann jeder Nutzer den Inhalt ausgelagerter Prozesse mitlesen: chmod 600 /swapfile.

swapon: /swapfile: swapon failed: Invalid argument Der häufigste Fehler. Entweder wurde mkswap vergessen, oder die Datei enthält Löcher. Im Kernelprotokoll steht dann zusätzlich swapon: swapfile has holes. Lösung: Datei löschen und mit dd statt fallocate neu anlegen.

Auf btrfs gilt derselbe Fehler plus BTRFS warning: swapfile must not be copy-on-write. Hier ist die Reihenfolge eine andere, die Datei muss leer erzeugt und vor dem Befüllen als nicht copy-on-write markiert werden. Ein Hinweis vorweg, der über einen laufenden Server entscheiden kann: truncate -s 0 und rm laufen auch dann durch, wenn unter dem Pfad noch ein aktiver Swap eingebunden ist. Der Kernel zeigt danach auf Blöcke, die es nicht mehr gibt. Führt swapon --show den Pfad als aktiv, gehört deshalb zwingend ein swapoff /swapfile davor.

truncate -s 0 /swapfile
chattr +C /swapfile

Danach wie gewohnt mit dd befüllen, chmod 600, mkswap, swapon. Auf komprimierten Subvolumes und in Snapshots funktioniert Swap weiterhin nicht.

swapon: /swapfile: swapon failed: Operation not permitted Sie sitzen in einem Container. LXC, OpenVZ und Docker teilen sich den Kernel des Wirts und dürfen keinen eigenen Swap einschalten. Prüfen mit:

systemd-detect-virt

Meldet der Befehl kvm, qemu oder none, läuft ein eigener Kernel und Swap ist möglich. Meldet er lxc, openvz oder docker, hilft nur mehr Arbeitsspeicher oder ein Produkt mit vollwertiger Virtualisierung. Die KVM-Rootserver und Dedicated Server von KernelHost bringen einen eigenen Kernel mit, Swap lässt sich dort uneingeschränkt einrichten.

dd: error writing '/swapfile': No space left on device Die Platte ist zu voll. Erst df -h, dann die halb geschriebene Datei mit rm /swapfile entfernen, sonst belegt sie weiter Platz. Auch hier gilt: Zeigt swapon --show den Pfad als aktiv an, gehört ein swapoff /swapfile vor das Löschen.

System startet nicht mehr, Notfallkonsole erscheint. Fast immer ein Tippfehler in /etc/fstab. Über die Konsole im Kundenbereich anmelden, dann mount -o remount,rw /, die fehlerhafte Zeile entfernen oder /etc/fstab.bak zurückkopieren, neu starten. Genau dafür wurde die Sicherungskopie vorher angelegt.

Unterschiede zwischen Debian 13, Debian 12, Ubuntu 24.04 und 22.04

Die Befehle sind auf allen vier Systemen identisch, der Ausgangszustand nicht.

  • Vorhandener Swap: Ubuntu Server aus dem ISO-Installer legt häufig /swap.img an, Debian aus dem Installer eine Swap-Partition. Cloud-Abbilder beider Distributionen kommen ohne Swap. Immer erst swapon --show.
  • systemd-oomd: Auf Ubuntu seit 22.04 ab Werk installiert und aktiv, auf beiden Debian-Versionen nicht Teil der Standardausstattung. Das erklärt, warum identische Software auf zwei scheinbar gleichen Systemen unterschiedlich sterben kann.
  • Datenbank: Debian 12 und Debian 13 liefern kein mysql-server, dort läuft immer MariaDB (10.11 unter Debian 12, 11.8 unter Debian 13). Ubuntu 22.04 und 24.04 haben beides. Die Standardwerte für innodb_buffer_pool_size unterscheiden sich entsprechend, und genau dieser Wert ist auf kleinen Servern die häufigste OOM-Ursache.
  • Java: Debian 12 kennt nur OpenJDK 17, Debian 13 nur OpenJDK 21, Ubuntu 22.04 und 24.04 decken 8 bis 21 ab. Eine JVM ohne gesetztes -Xmx nimmt sich standardmäßig ein Viertel des Arbeitsspeichers, bei mehreren Instanzen ist der OOM-Kill dann vorprogrammiert.
  • Kernelmeldungen: Format und Wortlaut der OOM-Meldung sind auf allen vier Systemen gleich, die Beispiele oben passen überall.
  • swappiness: überall 60 als Standard.

Wann Swap hilft und wann er das Problem nur verschiebt

Swap hilft zuverlässig bei kurzen Spitzen, etwa während eines Backups, eines Paketupgrades oder eines nächtlichen Imports. Er hilft bei Diensten, die viel Speicher belegen und dann tagelang nichts tun, denn diese Seiten dürfen ruhig auf der Platte liegen. Und er verschafft Ihnen im Ernstfall Minuten, in denen die SSH-Sitzung noch reagiert und Sie eingreifen können, statt vor einem toten Server zu stehen.

Swap hilft nicht, wenn der dauerhafte Bedarf schlicht über dem Arbeitsspeicher liegt. Dann beginnt das System zu thrashen: Es lagert ununterbrochen aus und wieder ein, die Load steigt auf zweistellige Werte, die CPU-Auslastung bleibt niedrig, alles wartet auf I/O. Praktisch ist das schlimmer als ein sauberer OOM-Kill, weil auch die Anmeldung nicht mehr durchkommt. Zwei Befehle zeigen, ob Sie in diesem Zustand sind:

vmstat 1 5
test -e /proc/pressure/memory && cat /proc/pressure/memory

Bei vmstat zählen die Spalten si und so. Dauerhaft dreistellige Werte bedeuten aktives Ein- und Auslagern. In /proc/pressure/memory ist full avg10 entscheidend: Werte über 10 heißen, dass das gesamte System zehn Prozent der Zeit auf Speicher wartet. Über 40 ist die Maschine praktisch tot. Die Datei existiert allerdings nur, wenn Pressure Stall Information im Kernel aktiv ist. Die Standardkernel von Debian und Ubuntu bringen das mit, andere Kernel nicht zwangsläufig. Deshalb die Absicherung mit test -e: Fehlt die Datei, bleibt die Ausgabe leer, statt dass Sie ein No such file or directory für einen Defekt halten. Nachrüsten lässt sich PSI über den Kernel-Bootparameter psi=1.

Welche Prozesse tatsächlich im Swap liegen, beantwortet diese Zeile:

grep VmSwap /proc/*/status | sort -k2 -rn | head

Ebenfalls nichts bringt Swap gegen ein cgroup-Limit (CONSTRAINT_MEMCG), gegen mit mlock festgepinnten Speicher und gegen eine JVM, deren Heap größer konfiguriert ist als der vorhandene RAM. Der Garbage Collector läuft regelmäßig über den gesamten Heap und holt jede ausgelagerte Seite sofort zurück.

Die drei Werkzeuge für den Fall, dass Swap nicht reicht

zram legt einen komprimierten Auslagerungsbereich im RAM selbst an. Er ist um Größenordnungen schneller als eine Datei auf der Platte und verschafft je nach Datenlage 20 bis 40 Prozent effektiv mehr Speicher:

apt update
apt install -y zram-tools

Konfiguriert wird in /etc/default/zramswap über ALGO=zstd und PERCENT=50, danach systemctl restart zramswap. Kontrolle mit zramctl und erneut swapon --show, dort taucht dann /dev/zram0 auf. Mit zram gehört vm.swappiness hoch auf 100 bis 180, weil das Auslagern hier billig ist.

earlyoom greift ein, bevor der Kernel das System einfriert, und tötet gezielt statt nach Heuristik:

apt install -y earlyoom

In /etc/default/earlyoom setzen Sie über EARLYOOM_ARGS die Schwellen und schützen wichtige Prozesse, etwa mit -m 5 -s 5 --avoid '(^|/)(sshd|systemd)$'. Damit bleibt die SSH-Anmeldung erreichbar, während der Speicherfresser fällt.

Feste Grenzen pro Dienst sind die sauberste Lösung, wenn ein bestimmter Dienst regelmäßig ausbricht. Über systemctl edit mariadb tragen Sie MemoryHigh=1200M und MemoryMax=1500M ein. Der Dienst wird dann gebremst und notfalls allein beendet, statt den ganzen Server mitzureißen. Kontrolle über systemctl show mariadb -p MemoryMax.

Der eigentliche Fix bleibt in den meisten Fällen aber die Anwendungskonfiguration: innodb_buffer_pool_size auf ein realistisches Maß, pm.max_children anhand des tatsächlichen Speicherbedarfs pro Worker, ein gesetztes -Xmx für jede JVM. Swap ist das Sicherheitsnetz, nicht die Lösung.

Rückbau, falls es nicht passt

Der Weg zurück ist kurz und sollte in dieser Reihenfolge gehen:

swapoff /swapfile

Der Befehl kann bei stark belegtem Swap mehrere Minuten laufen, weil alle Seiten zurück in den RAM müssen. Läuft er auf swapoff: /swapfile: swapoff failed: Cannot allocate memory, ist im RAM kein Platz für den Rücktransport, dann müssen zuerst Dienste gestoppt werden. Erst nach erfolgreichem swapoff die fstab-Zeile entfernen und die Datei löschen:

rm /swapfile
swapon --show

Die Datei zu löschen, solange sie noch eingebunden ist, führt zu einem System, dessen Speicherverwaltung auf einen nicht mehr existierenden Inode zeigt. Das endet unschön. Zum Schluss noch einmal free -h und ein Neustart als Gegenprobe.

Häufige Fragen

Wie viel Swap brauche ich auf einem Server?
Auf Servern gilt nicht mehr die alte Regel vom Doppelten des Arbeitsspeichers. Sinnvoll sind 1 bis 2 GB bei 1 GB RAM, 2 GB bei 2 GB RAM und 2 bis 4 GB bei 4 bis 8 GB RAM. Ab 16 GB reichen 4 GB. Swap, den Sie tatsächlich vollständig benutzen, macht das System durch dauerndes Ein- und Auslagern unbedienbar, mehr Platz ist also keine Reserve, sondern nur eine längere Agonie.
Warum zeigt journalctl -k keinen OOM-Kill, obwohl es einen gab?
Weil die Option -k implizit -b setzt und damit nur den aktuellen Bootvorgang anzeigt. Ist der Server nach dem Vorfall neu gestartet, sehen Sie nichts. Nutzen Sie journalctl -k -b -1 für den vorherigen Start oder journalctl --since "7 days ago" --grep "Out of memory|oom-kill" für einen Zeitraum. Voraussetzung ist ein persistentes Journal, prüfbar über ls -d /var/log/journal, das auf Debian und Ubuntu ab Werk vorhanden ist. Meldet journalctl -k -b -1 stattdessen "No journal boot entry found for the specified boot (-1)", ist einfach kein früherer Bootvorgang gespeichert.
Woran erkenne ich, ob der Kernel oder ein systemd-Limit den Prozess beendet hat?
Am Feld constraint in der Kernelmeldung. CONSTRAINT_NONE bedeutet, dem gesamten System ist der Speicher ausgegangen, hier hilft Swap. CONSTRAINT_MEMCG bedeutet, eine einzelne Control-Group hat ihr Limit gerissen, hier hilft Swap nicht. Prüfen Sie zusätzlich systemctl show DIENST -p MemoryMax sowie den Zähler oom_kill in der Datei memory.events der jeweiligen Control-Group.
Warum schlägt swapon mit "Invalid argument" fehl?
Entweder wurde mkswap vergessen, oder die Datei wurde mit fallocate angelegt und enthält nicht geschriebene Bereiche. Im Kernelprotokoll steht dann swapon: swapfile has holes. Legen Sie die Datei stattdessen mit dd if=/dev/zero an. Auf btrfs muss die Datei zusätzlich vorher mit truncate -s 0 und chattr +C als nicht copy-on-write markiert werden, und zwar erst nach einem swapoff /swapfile, weil das Leeren einer eingebundenen Swap-Datei den Kernel auf nicht mehr vorhandene Blöcke zeigen lässt. Verweigert bereits mkswap den Dienst mit "/swapfile is mounted; will not make swapspace", ist unter dem Pfad noch ein aktiver Swap eingebunden, sichtbar über swapon --show.
Kann ich Swap in einem Container einrichten?
Nein. LXC, OpenVZ und Docker nutzen den Kernel des Wirtssystems und dürfen keinen eigenen Swap aktivieren, swapon quittiert das mit "Operation not permitted". Prüfen Sie mit systemd-detect-virt: Bei kvm, qemu oder none läuft ein eigener Kernel und Swap ist möglich. In einem Container hilft nur mehr Arbeitsspeicher oder ein Wechsel auf vollwertige Virtualisierung.
Bedeutet vm.swappiness=0, dass gar nicht mehr ausgelagert wird?
Nein. Seit Kernel 3.5 verhindert der Wert nur das vorsorgliche Auslagern. Wird der Speicher knapp, lagert der Kernel trotzdem aus, bevor er einen Prozess beendet. Wer Swap wirklich abschalten will, muss swapoff nutzen. Der Wertebereich reicht auf allen aktuellen Debian- und Ubuntu-Kerneln von 0 bis 200, der Standard ist überall 60.

Linux Swap Troubleshooting Debian Ubuntu Serververwaltung