Hohe Swap-Nutzung trotz freiem RAM troubleshooten
AI generated
$
/etc
Linux · Troubleshooting · Speicherverwaltung · MySQL
Hohe Swap-Nutzung trotz freiem RAM troubleshooten
Warum der Kernel Speicher auslagert, obwohl free -h Reserven zeigt

Mehrere Gigabyte Swap-Nutzung bei gleichzeitig reichlich freiem Arbeitsspeicher in free -h wirkt paradox, ist aber meistens proaktives, gewolltes Kernel-Verhalten und kein Fehler. Dieser Leitfaden zeigt, wie man mit Pressure Stall Information, vmstat und smaps zwischen harmlosem und tatsächlich problematischem Swapping unterscheidet, welche Rolle Swappiness wirklich spielt und wann MySQL-Buffer-Pool-Konfiguration die eigentliche Ursache ist.

17 Min. Lesezeit PSI · vmstat · swappiness · smaps Linux · Troubleshooting · MySQL

1. Warum Swap-Nutzung bei freiem RAM kein Widerspruch ist

Der Anblick von mehreren Gigabyte belegtem Swap in free -h, während gleichzeitig reichlich freier Arbeitsspeicher gemeldet wird, wirkt auf den ersten Blick wie ein Fehler im System. Tatsächlich ist dieses Verhalten in den meisten Fällen beabsichtigt: Der Linux-Kernel lagert selten genutzte Speicherseiten proaktiv aus, sobald sie längere Zeit nicht angefasst wurden, um den dadurch gewonnenen physischen Speicher für den Page-Cache und aktiv genutzte Anwendungsdaten verfügbar zu machen. Diese Strategie folgt der Grundannahme, dass ungenutzter RAM verschwendeter RAM ist, und priorisiert aktive Daten gegenüber selten gebrauchtem, aber weiterhin allokiertem Speicher.

Das eigentliche Problem entsteht erst, wenn genau diese ausgelagerten Seiten kurz darauf wieder gebraucht werden und der Kernel sie unter Zeitdruck von der deutlich langsameren Swap-Partition zurückholen muss. Diese Situation, bekannt als Thrashing, äußert sich als spürbare Latenz und hohe I/O-Wartezeiten, obwohl free -h nach wie vor ausreichend freien Speicher anzeigt. Die zentrale Herausforderung bei der Diagnose liegt deshalb nicht in der Feststellung, dass Swap genutzt wird, sondern in der Unterscheidung zwischen harmlosem, proaktivem Auslagern und tatsächlich schädlichem, wiederholtem Thrashing.

2. free -h richtig lesen: verfügbar ist nicht gleich frei

Ein häufiger Interpretationsfehler bei free -h ist die Verwechslung der Spalten free und available. Die Spalte free zeigt komplett ungenutzten Speicher, der weder für Anwendungen noch für den Page-Cache reserviert ist, während available zusätzlich den Speicher einschließt, der aktuell im Page-Cache liegt, aber bei Bedarf sofort und ohne Performance-Einbußen freigegeben werden kann. Ein niedriger free-Wert bei hohem available-Wert ist völlig normal und zeigt lediglich, dass der Kernel den Speicher effizient für Caching nutzt, nicht dass ein Engpass droht.

Für die Bewertung der Swap-Nutzung ist entscheidend, die used-Spalte der Swap-Zeile über die Zeit zu beobachten statt einen einzelnen Wert zu bewerten. Ein seit Tagen stabiler Swap-Wert, der sich nicht verändert, deutet auf länger zurückliegendes, einmaliges Auslagern hin und ist meist unproblematisch. Ein Swap-Wert, der kontinuierlich wächst und gleichzeitig mit steigender CPU-Zeit im %wa-Feld (I/O-Wartezeit) von top einhergeht, ist dagegen ein klares Warnsignal für aktives, belastendes Swapping, das die Anwendungsperformance tatsächlich beeinträchtigt.


# free vs. available — the distinction that matters
free -h
#               total        used        free      shared  buff/cache   available
# Mem:           31Gi        18Gi       1.2Gi       412Mi        12Gi        13Gi
# Swap:         8.0Gi       2.1Gi       5.9Gi

# A stable swap value that hasn't changed in days is usually harmless
# Log it over time to distinguish a one-time event from ongoing pressure
watch -n 300 'free -h | grep Swap'

3. vmstat und si/so: Aktivität statt Bestand messen

Während free -h nur einen Momentzustand zeigt, liefert vmstat 1 die tatsächliche Swap-Aktivität in Echtzeit über die Spalten si (swap in, Seiten die von der Swap-Partition zurück in den RAM geladen werden) und so (swap out, Seiten die neu ausgelagert werden). Dauerhaft hohe Werte in beiden Spalten gleichzeitig sind das entscheidende Signal für Thrashing: Der Kernel lagert Seiten aus und muss sie kurz darauf wieder zurückholen, was auf einen echten Speicherengpass hindeutet, bei dem der verfügbare RAM für die aktive Arbeitslast schlicht nicht ausreicht.

Gelegentliche kurze Spitzen in so ohne entsprechende si-Aktivität sind dagegen unbedenklich und entsprechen genau dem proaktiven Auslagern selten genutzter Seiten aus dem vorherigen Abschnitt. Die Faustregel: Ein einmaliger Ausschlag in so gefolgt von Stille ist normal, ein wiederkehrendes Muster aus si und so im Wechsel über mehrere Minuten ist ein Alarmsignal, das eine tiefere Untersuchung der Speicheranforderungen rechtfertigt.


# Live view of swap in/out activity, refreshed every second
vmstat 1 10

# procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
#  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
#  2  1  2150400 125600 45200 12800000  0    0   120   340 1200 2400 12  4 82  2  0
#  3  4  2151200 118400 45200 12790000 45  180   890  1200 1800 3100 18  9 55 18  0
#                                      ^^^  ^^^ — sustained si+so = real thrashing

# Aggregate view without the noise: only si/so columns over time
vmstat 1 60 | awk '{print $7, $8}'

4. Pressure Stall Information: Den echten Speicherdruck messen

Pressure Stall Information (PSI), verfügbar seit Kernel 4.20 unter /proc/pressure/memory, ist das präziseste verfügbare Werkzeug, um Speicherdruck direkt zu quantifizieren, statt ihn aus Indizien wie Swap-Nutzung abzuleiten. PSI misst, wie viel Prozent der Zeit mindestens ein Prozess (some) beziehungsweise alle Prozesse gleichzeitig (full) durch fehlenden Speicher blockiert waren, aggregiert über 10 Sekunden, 60 Sekunden und 5 Minuten. Ein full avg10-Wert nahe Null bedeutet, dass trotz Swap-Nutzung praktisch kein Prozess durch Speicherknappheit spürbar ausgebremst wurde, was die zuvor beobachtete Swap-Aktivität als unproblematisch einordnet.

Steigt der full avg10-Wert dagegen über einen niedrigen einstelligen Prozentbereich, verbringen Anwendungen messbare Zeit blockiert, weil sie auf ausgelagerte Seiten warten, die gerade zurückgeholt werden. Dieser einzelne Wert ersetzt in der Praxis die mühsame manuelle Korrelation zwischen vmstat-Aktivität, Anwendungslatenz und CPU-Wartezeit und sollte der erste Blick bei jedem Verdacht auf ein Swap-Problem sein, noch vor free -h oder vmstat.


# The single most reliable indicator of actual memory pressure
cat /proc/pressure/memory

# some avg10=2.34 avg60=1.87 avg300=0.95 total=48291823
# full avg10=0.12 avg60=0.08 avg300=0.03 total=1204958
#                  ^^^^^^^^^ — near-zero "full" means no real stalling

# Alert threshold suggestion: full avg10 consistently above 5% warrants investigation
awk '/^full/ {print $2}' /proc/pressure/memory | grep -oP 'avg10=\K[0-9.]+'

5. Swappiness richtig verstehen und einordnen

Der Parameter vm.swappiness (Standardwert meist 60) steuert, wie aggressiv der Kernel Speicherseiten gegenüber dem Page-Cache priorisiert, wenn Speicher knapp wird, nicht ob überhaupt geswapped wird. Ein häufiges Missverständnis ist die Annahme, vm.swappiness=0 deaktiviere Swap vollständig. Tatsächlich bedeutet der Wert 0 seit Kernel 3.5 nur, dass Swap ausschließlich als letztes Mittel genutzt wird, kurz bevor der OOM-Killer eingreifen müsste, während Werte zwischen 1 und 100 die relative Gewichtung zwischen dem Verdrängen von Page-Cache und dem Auslagern von Anwendungsspeicher festlegen.

Für Datenbankserver wie MySQL, bei denen der eigene Buffer Pool bereits die effektivste Cache-Schicht darstellt, ist ein niedrigerer Wert wie vm.swappiness=10 häufig sinnvoll, weil er dem Kernel signalisiert, den Page-Cache stärker zu bevorzugen, statt aktiv genutzten Anwendungsspeicher zugunsten von Dateisystem-Caching auszulagern. Ein Swappiness-Wert allein löst aber kein zugrunde liegendes Kapazitätsproblem, er verschiebt nur, welche Art von Speicher zuerst betroffen ist, wenn der Druck tatsächlich ansteigt.


# /etc/sysctl.d/99-swappiness.conf
# Lower value favors keeping application memory resident,
# at the cost of evicting page cache more aggressively under pressure.
# Recommended starting point for database servers (MySQL/MariaDB).
vm.swappiness = 10

sudo sysctl --system

# Verify the active value
cat /proc/sys/vm/swappiness

6. Mit smaps herausfinden, was tatsächlich ausgelagert wurde

Wenn PSI einen echten Speicherdruck bestätigt, ist der nächste Schritt herauszufinden, welcher Prozess für die ausgelagerten Seiten verantwortlich ist. /proc/[pid]/status liefert mit VmSwap die pro Prozess ausgelagerte Speichermenge, während smem -st swap eine nach Swap-Nutzung sortierte Übersicht aller Prozesse liefert. Ein Prozess mit auffällig hohem VmSwap-Wert im Vergleich zu seinem VmRSS deutet darauf hin, dass ein erheblicher Teil seines Speichers seit längerem nicht aktiv genutzt wurde, was bei einem Datenbankserver oder einem PHP-FPM-Master-Prozess mit selten genutzten, aber allokierten Puffern durchaus normal sein kann.

Für eine noch genauere Analyse zeigt /proc/[pid]/smaps den Swap-Anteil pro einzelnem Memory-Mapping, was hilft, zwischen ausgelagertem Heap-Speicher, ausgelagerten Shared-Memory-Segmenten und ausgelagerten Bibliotheks-Mappings zu unterscheiden. Diese Aufschlüsselung ist besonders wertvoll, wenn der Verdacht besteht, dass eine bestimmte Anwendungskomponente, etwa ein selten genutzter Admin-Bereich einer Magento-Installation, unnötig viel Speicher allokiert, der dann zu Recht ausgelagert wird, statt dass ein echtes Konfigurationsproblem vorliegt.


# Per-process swap usage, sorted highest first
smem -st swap

#   PID User     Command                         Swap      USS      PSS      RSS
#  1823 mysql    /usr/sbin/mysqld                512.0M   890.2M   920.4M  1024.8M
#  4821 www-data php-fpm: master process         128.4M    12.1M    18.9M    22.4M

# Breakdown of swapped memory within a single process's mappings
grep -B2 "^Swap:" /proc/1823/smaps | grep -A2 "^7f" | head -30

7. MySQL und der Buffer Pool: Ein häufiger Sonderfall

Bei MySQL-Servern ist Swap-Nutzung ein besonders häufiges und gleichzeitig besonders kritisches Thema, weil der InnoDB Buffer Pool bewusst so konfiguriert wird, dass er einen Großteil des verfügbaren RAM belegt, um Festplattenzugriffe zu minimieren. Wird innodb_buffer_pool_size zu großzügig bemessen, etwa bei 80 Prozent des Gesamtspeichers auf einem Server, der zusätzlich PHP-FPM-Worker und andere Dienste betreibt, konkurriert der Buffer Pool aktiv mit diesen Diensten um physischen Speicher, und der Kernel beginnt, selten genutzte Buffer-Pool-Seiten auszulagern.

Das eigentliche Problem dabei: Ausgelagerte Buffer-Pool-Seiten sind für MySQL nutzlos, sobald sie tatsächlich für eine Abfrage gebraucht werden, weil das Zurückholen von der Swap-Partition um Größenordnungen langsamer ist als ein direkter Festplattenzugriff über InnodB selbst gewesen wäre. In diesem Fall ist die Lösung nicht eine Anpassung der Swappiness, sondern eine korrekte Dimensionierung von innodb_buffer_pool_size unter Berücksichtigung aller anderen Dienste auf demselben Server, typischerweise bei 60 bis 70 Prozent des verfügbaren RAM statt einer pauschalen 80-Prozent-Regel ohne Rücksicht auf Nebendienste.

8. cgroup-v2 Memory Pressure für Container-Workloads

In containerisierten Umgebungen liefert cgroup v2 mit memory.pressure dieselbe PSI-Metrik wie das systemweite /proc/pressure/memory, aber isoliert auf die jeweilige Cgroup, was für Docker-Container und systemd-Services mit eigenem Speicherlimit besonders wertvoll ist. Ein Container, der sein memory.max-Limit erreicht, beginnt zu swappen (sofern memory.swap.max nicht auf 0 gesetzt ist) oder wird vom Cgroup-OOM-Killer beendet, unabhängig vom systemweiten Speicherzustand des Hosts. Die systemweite free -h-Ausgabe kann dabei völlig unauffällig aussehen, während ein einzelner Container bereits unter erheblichem internen Speicherdruck steht.

Für Magento-Setups mit mehreren Containern auf demselben Host ist die gezielte Überwachung von memory.pressure pro Cgroup deshalb aussagekräftiger als die systemweite Ansicht, weil sie genau zeigt, welcher einzelne Dienst tatsächlich unter Druck steht, statt einen aggregierten Wert zu liefern, der lokale Engpässe verschleiern kann.


# Per-cgroup memory pressure, isolated from the rest of the host
cat /sys/fs/cgroup/system.slice/docker-<container-id>.scope/memory.pressure

# Current memory limit and swap configuration for a specific cgroup
cat /sys/fs/cgroup/system.slice/docker-<container-id>.scope/memory.max
cat /sys/fs/cgroup/system.slice/docker-<container-id>.scope/memory.swap.max

9. Normales vs. problematisches Swapping im Vergleich

Die folgende Übersicht fasst die wichtigsten Signale zusammen, um zwischen harmlosem und tatsächlich problematischem Swapping zu unterscheiden.

Signal Normal Problematisch
Swap used (free -h) Stabil über Tage, keine Veränderung Kontinuierlich wachsend
vmstat si/so Einmaliger so-Ausschlag, dann Ruhe Anhaltender si/so-Wechsel
PSI full avg10 Nahe 0 Prozent Deutlich über 5 Prozent
Anwendungslatenz Unverändert Spürbar erhöht, korreliert mit so

Erst wenn mehrere dieser Signale gleichzeitig in die problematische Spalte fallen, insbesondere ein erhöhter PSI-Wert in Kombination mit anhaltender si/so-Aktivität, liegt tatsächliches Thrashing vor, das eine Kapazitätserweiterung oder eine Anpassung der Speicherkonfiguration rechtfertigt. Ein isoliert betrachteter, stabiler Swap-Wert ohne diese begleitenden Signale ist dagegen kein Handlungsbedarf, sondern normales, effizientes Kernel-Verhalten.

Mironsoft

Linux-Speicheranalyse und Datenbank-Tuning für Magento-Infrastruktur

Swap-Alarme ohne echten Speicherdruck?

Wir analysieren eure Speichernutzung mit PSI und vmstat, unterscheiden harmloses von tatsächlich problematischem Swapping und dimensionieren MySQL Buffer Pool sowie Swappiness passend zu eurer realen Arbeitslast.

Speicherdruck-Audit

PSI-basierte Analyse, ob Swap-Nutzung tatsächlich Anwendungen ausbremst

MySQL-Tuning

Buffer-Pool-Dimensionierung unter Berücksichtigung aller Dienste auf dem Server

Kapazitätsplanung

Reale Engpässe von harmlosem, proaktivem Auslagern zuverlässig trennen

10. Zusammenfassung

Hohe Swap-Nutzung trotz freiem RAM in free -h ist in den meisten Fällen kein Fehler, sondern proaktives Kernel-Verhalten, das selten genutzte Speicherseiten zugunsten von Page-Cache und aktiv genutzten Daten auslagert. Die entscheidende Frage ist nicht, ob Swap genutzt wird, sondern ob dieses Auslagern tatsächlich zu spürbarem Thrashing führt. Pressure Stall Information unter /proc/pressure/memory liefert dafür die präziseste, direkt interpretierbare Kennzahl, ergänzt durch anhaltende si/so-Aktivität in vmstat als Bestätigung.

Swappiness beeinflusst nur, welche Art von Speicher zuerst betroffen ist, löst aber kein Kapazitätsproblem selbst. Bei Datenbankservern ist die korrekte Dimensionierung von innodb_buffer_pool_size unter Berücksichtigung aller Nebendienste oft wichtiger als jede Swappiness-Anpassung. Wer PSI, vmstat und smaps kombiniert einsetzt, unterscheidet zuverlässig zwischen normalem, effizientem Speicherverhalten und einem tatsächlichen Engpass, der eine Kapazitätserweiterung rechtfertigt.

Swap-Nutzung trotz freiem RAM: Das Wichtigste auf einen Blick

Grundverhalten

Der Kernel lagert selten genutzte Seiten proaktiv aus, um Page-Cache und aktive Daten zu priorisieren.

Wichtigste Kennzahl

PSI full avg10 aus /proc/pressure/memory zeigt direkt, ob Prozesse tatsächlich ausgebremst werden.

Swappiness-Rolle

Steuert nur die Priorität zwischen Page-Cache und Anwendungsspeicher, löst kein Kapazitätsproblem.

MySQL-Sonderfall

innodb_buffer_pool_size korrekt dimensionieren statt Swappiness als Sofortlösung zu betrachten.

11. FAQ: Hohe Swap-Nutzung trotz freiem RAM troubleshooten

1Warum wird Swap bei freiem RAM genutzt?
Proaktives Auslagern selten genutzter Seiten zugunsten von Page-Cache und aktiven Daten. Beabsichtigt, kein Fehler.
2Unterschied free vs. available?
free ist komplett ungenutzt, available schließt sofort freigebbaren Page-Cache mit ein.
3Echtes Thrashing in vmstat erkennen?
Anhaltend hohe si und so gleichzeitig über mehrere Minuten, nicht ein einmaliger Ausschlag.
4Was ist Pressure Stall Information?
Misst direkt, wie viel Prozent der Zeit Prozesse durch Speicherknappheit blockiert waren.
5Deaktiviert swappiness=0 Swap komplett?
Nein, seit Kernel 3.5 nur letztes Mittel kurz vor OOM-Kill. Komplett deaktivieren braucht swapoff -a.
6Welche Swappiness für MySQL?
Oft vm.swappiness=10, da der Buffer Pool schon die effektivste Cache-Schicht ist.
7Welcher Prozess hat Speicher ausgelagert?
smem -st swap sortiert alle Prozesse nach Swap-Nutzung.
8Warum ist Swap bei MySQL kritisch?
Ausgelagerte Buffer-Pool-Seiten sind beim Zurückholen um Größenordnungen langsamer als InnoDB-Festplattenzugriff.
9Speicherdruck pro Container überwachen?
cgroup v2 memory.pressure liefert PSI isoliert pro Container, aussagekräftiger als der Host-Wert.
10Wann Kapazität erweitern statt konfigurieren?
Bei dauerhaft hohem PSI full avg10 über 5 Prozent zusammen mit anhaltender si/so-Aktivität und spürbarer Latenz.