linux-kernel-advanced performance tuning memory oom-killer cgroups advanced

Memory Limits: OOM Killer & Restrictions (Artikel 376)

Analyse der Speicherlimitierung und des OOM-Killers unter Linux. Erfahren Sie alles über Speicher-Schwellenwerte, das Verhalten des Kernels bei Ressourcenmangel und die Rettung von Prozessen.

# OOM Mastery: Speicherlimits und der Überlebenskampf des Kernels

TL;DR / Management Summary Arbeitsspeicher ist eine endliche Ressource. Wenn er zur Neige geht, muss der Kernel eine Entscheidung treffen: Welcher Prozess muss sterben, damit das Gesamtsystem überlebt? Das ist die Geburtsstunde des OOM-Killers (Out of Memory). In diesem Modul lernen wir, wie der Kernel seine Opfer wählt, wie wir mit Cgroups v2 sanfte (High) und harte (Max) Limits setzen und wie wir kritische Prozesse (z.B. SSH oder Datenbanken) vor dem OOM-Tod schützen.


# 1. Einführung & Architektur

Die Eskalationsstufen.

In Cgroups v2 gibt es drei Hebel zur Speichersteuerung:

  1. memory.low: Garantierter Speicher. Der Kernel versucht, diesen Bereich niemals anzufassen.
  2. memory.high: Sanftes Limit. Bei Überschreitung wird der Prozess gebremst und aggressiv gecached (Reclaim), aber nicht gekillt.
  3. memory.max: Hartes Limit. Wer mehr will, stirbt sofort (OOM).

# Die OOM-Logik (Mermaid)

graph TD
    A[Process requests RAM] --> B{Available?}
    B -->|Yes| C[Allocation Success]
    B -->|No| D{Cgroup Limit reached?}
    D -->|Yes| E[OOM Killer: Scope Group]
    D -->|No: System empty| F[OOM Killer: Scope Global]
    E/F --> G[Select Victim based on OOM-Score]
    G --> H[Send SIGKILL -9]
    H --> I[Free Memory]

# 2. Der OOM-Score: Wer stirbt zuerst?

Die Todesliste des Kernels.

Der Kernel berechnet für jeden Prozess einen Wert zwischen 0 und 1000. Je höher der Wert, desto wahrscheinlicher der Tod.

  • Faktoren: Aktueller RAM-Verbrauch, Prozess-Laufzeit, User-Status (Root/User) und der manuelle OOM-Score-Adjust.

# Den Score prüfen

cat /proc/<PID>/oom_score

# 3. Schutz kritischer Prozesse

Den adjust Hebel nutzen.

Sie können den Kernel anweisen, einen Prozess zu verschonen. Datei: /proc/<PID>/oom_score_adj

  • Range: -1000 (Niemals killen) bis +1000 (Immer zuerst killen).

# Beispiel: Datenbank schützen

# Setzt MySQL auf die sicherste Stufe
echo -1000 | sudo tee /proc/$(pgrep mysqld)/oom_score_adj

# 4. Day-2 Operations: OOM-Analyse

Was ist passiert?

Ein OOM-Event hinterlässt einen “Tatortbericht” im Kernel-Log.

# Logs lesen

dmesg -T | grep -i "out of memory"
# Suchen Sie nach "Killed process <PID> (name)"

# Die Anatomie eines OOM-Logs

Der Kernel gibt vor dem Kill eine Tabelle aller Prozesse aus. Achten Sie auf:

  • rss: Real belegter Speicher.
  • swap-ents: Genutzter Swap.
  • oom_score_adj: Wurde der Prozess künstlich benachteiligt?

# 5. Troubleshooting & “War Stories”

Wenn die Applikation lautlos stirbt.

# Story 1: “Der Mystery-Exit im Container”

Symptom: Ein Docker-Container startet neu, aber in den App-Logs steht kein Fehler. Ursache: Das Cgroup-Limit (memory.max) wurde erreicht. Der Host-Kernel hat den Prozess gekillt. Da der Exit-Code 137 (SIGKILL) ist, konnte die Applikation keinen Fehler mehr schreiben. Lösung: Prüfen Sie journalctl -ke auf dem Host. Dort steht der wahre Grund für den Exit. Erhöhen Sie das Limit oder optimieren Sie den Speicherverbrauch.

# Story 2: “Das Memory-Leak im Cache”

Symptom: Der Server nutzt 100% RAM, aber top zeigt nur 10% bei den Prozessen. Der OOM-Killer wird trotzdem aktiv. Ursache: Page-Cache Inflation. Der Kernel hat zu viele Datei-Caches im RAM, kann sie aber nicht schnell genug freigeben (z.B. bei langsamer Disk). Lösung: Passen Sie vm.min_free_kbytes an, damit der Kernel immer eine kleine Reserve für sich selbst behält (siehe Artikel 368).


# 6. Fazit & Empfehlung

  • Strategie: Setzen Sie memory.high etwas unter memory.max, um der Applikation die Chance zu geben, Speicher selbst freizugeben (Garbage Collection), bevor sie gekillt wird.
  • Überwachung: Nutzen Sie Tools wie oomd (Systemd OOM Dämon), um Speicherengpässe im User-Space eleganter zu lösen.
  • Wartung: Sorgen Sie dafür, dass systemkritische Dienste (SSH, Monitoring) immer einen negativen oom_score_adj haben.

# Anhang: Cheatsheet

Aufgabe Befehl / Pfad
OOM Score prüfen cat /proc/<PID>/oom_score
Score anpassen echo -500 > /proc/<PID>/oom_score_adj
v2 Max Limit cat memory.max
v2 High Limit cat memory.high
OOM Events (Global) grep -i oom /var/log/messages
OOM Kill erzwingen echo f > /proc/sysrq-trigger (VORSICHT!)
systemd Schutz OOMScoreAdjust=-1000 in Unit-File
Swap Status swapon -s