Linux-Speicherverwaltung verstehen: RAM, Swap, Cache
$
/etc
Linux · Kernel · RAM · Performance
Linux-Speicherverwaltung verstehen: RAM, Swap, Cache
Warum free -h täuscht und was wirklich zählt

Wer free -h zum ersten Mal sieht, hält den Arbeitsspeicher oft fälschlich für knapp, weil buff/cache als belegt erscheint. Dieser Artikel erklärt, wie der Page Cache brachliegenden RAM für Performance nutzt, warum Swap ein Overflow-Mechanismus statt primärer Speicher ist, und wie sich der tatsächliche Speicherzustand über proc meminfo präzise beurteilen lässt.

18 Min. Lesezeit free · /proc/meminfo · Page Cache Swap · OOM-Killer · cgroups

1. Warum free -h zunächst alarmierend wirkt

Wer zum ersten Mal free -h auf einem produktiven Server ausführt, erschrickt oft: Die Spalte used zeigt einen hohen Wert, frei wirkt kaum Speicher übrig. Der Eindruck täuscht, denn free berücksichtigt in der klassischen Darstellung nicht, dass ein großer Teil des vermeintlich belegten Speichers jederzeit wieder freigegeben werden kann. Der Linux-Kernel folgt der Philosophie, dass ungenutzter Arbeitsspeicher verschwendeter Arbeitsspeicher ist, und füllt freien RAM konsequent mit Daten aus dem Dateisystem-Cache, solange kein Prozess ihn dringender benötigt.

Die entscheidende Spalte ist nicht used, sondern available. Sie schätzt, wie viel Speicher tatsächlich für neue Anwendungen bereitsteht, ohne dass geswappt werden muss, und berücksichtigt dabei reclaimable Anteile des Page Cache. Ein Server mit 32 GB RAM, 18 GB used und 13 GB available ist keineswegs am Limit, sondern nutzt seinen Speicher effizient. Wer stattdessen nur auf used schaut und panisch Cache leert oder RAM aufrüstet, löst ein Problem, das gar nicht existiert, und verschenkt dabei echte Performance-Vorteile des Caching-Mechanismus.


# Typical free -h output on a server with 32 GB RAM
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           31Gi        18Gi       412Mi       1.2Gi        13Gi        13Gi
Swap:         2.0Gi       128Mi       1.9Gi

# "used" looks high and "free" looks almost empty, but "available" tells the real story
# available accounts for reclaimable buff/cache, not just literally unused pages

# Show raw kibibytes instead of human-readable values for scripting
$ free -k --wide

2. Der Page Cache: RAM sinnvoll nutzen statt brachliegen zu lassen

Der Page Cache speichert kürzlich gelesene oder geschriebene Dateiinhalte im RAM, damit wiederholte Zugriffe nicht erneut von der Festplatte oder SSD gelesen werden müssen. Für einen Magento-Shop mit häufig gelesenen Konfigurationsdateien, Session-Daten oder Datenbank-Dateien bedeutet das spürbar kürzere Zugriffszeiten, weil der Kernel diese Blöcke transparent im Hintergrund vorhält. Anwendungen selbst müssen dafür nichts konfigurieren, der Cache arbeitet vollständig transparent auf Kernel-Ebene und wächst automatisch, solange freier Speicher vorhanden ist.

Sobald ein Prozess zusätzlichen Speicher anfordert, gibt der Kernel Cache-Seiten ohne Verzögerung frei, priorisiert dabei aber häufig genutzte Seiten gegenüber selten gelesenen. Dieser Mechanismus erklärt, warum buff/cache in free -h mit steigender Systemlaufzeit kontinuierlich wächst, bis fast der gesamte freie Speicher belegt erscheint, obwohl das System vollkommen normal funktioniert. Ein manuelles Leeren des Caches über drop_caches ist in Produktionsumgebungen fast nie sinnvoll, da es die Performance kurzfristig verschlechtert, weil erneute Festplattenzugriffe nötig werden, bis der Cache sich wieder aufgebaut hat.

3. /proc/meminfo: die Datenquelle hinter free

/proc/meminfo liefert die Rohdaten, aus denen free, vmstat und die meisten Monitoring-Tools ihre Werte berechnen, und lohnt sich für alle, die Speicherprobleme wirklich verstehen wollen. Die Felder MemTotal, MemFree und MemAvailable bilden das Fundament: MemFree zeigt komplett ungenutzten Speicher, während MemAvailable eine realistische Schätzung liefert, wie viel Speicher für neue Anwendungen bereitsteht, wenn reclaimable Caches berücksichtigt werden. Seit Kernel 3.14 ist MemAvailable die zuverlässigste einzelne Kennzahl für Kapazitätsplanung und Alerting.

Weitere wichtige Felder sind Cached für den Page Cache, Buffers für Metadaten-Puffer von Blockgeräten, Dirty für noch nicht auf die Platte geschriebene Änderungen und SwapFree für ungenutzten Swap-Speicher. Die Felder Slab und SReclaimable zeigen kernelinternen Speicher für Datenstrukturen wie Dentries und Inodes, von dem ein Teil bei Speicherdruck ebenfalls freigegeben werden kann. Wer Speicherprobleme diagnostiziert, sollte immer mehrere dieser Felder gemeinsam betrachten, statt sich auf eine einzelne Zahl zu verlassen.


# Read the raw counters behind free and vmstat
$ cat /proc/meminfo | head -20
MemTotal:       32860192 kB
MemFree:          432108 kB
MemAvailable:   13584220 kB
Buffers:          210344 kB
Cached:         12980112 kB
SwapCached:         2048 kB
SwapTotal:       2097148 kB
SwapFree:        1966080 kB
Dirty:              8420 kB
Writeback:              0 kB
Slab:              892340 kB
SReclaimable:      612880 kB
SUnreclaim:         279460 kB

# MemAvailable already accounts for reclaimable Cached + SReclaimable
# Compare MemFree (raw, tiny) vs MemAvailable (realistic, much larger)

4. Swap: Overflow-Speicher, nicht primärer Arbeitsspeicher

Swap ist in modernen Linux-Systemen kein primärer Speicherersatz, sondern ein Sicherheitsnetz für seltene Lastspitzen und selten genutzte Speicherseiten. Der Kernel lagert bevorzugt Speicherseiten aus, die lange nicht mehr angefasst wurden, damit der schnellere RAM für aktiv genutzte Daten frei bleibt. Ein moderater Swap-Verbrauch von wenigen hundert Megabyte auf einem System mit viel RAM ist deshalb völlig normal und kein Alarmsignal, solange die Swap-Aktivität selbst, gemessen an si und so in vmstat, nahe null bleibt.

Problematisch wird Swap erst, wenn aktiv genutzte Seiten kontinuierlich aus- und wieder eingelagert werden, ein Zustand, der als Thrashing bezeichnet wird und die Systemleistung dramatisch einbrechen lässt, weil Festplattenzugriffe um Größenordnungen langsamer sind als RAM-Zugriffe. Auf Servern mit SSD-basiertem Swap ist der Effekt weniger dramatisch als bei rotierenden Festplatten, aber immer noch spürbar. Die Kennzahl si (swap in) und so (swap out) aus vmstat 1 zeigt in Echtzeit, ob gerade aktiv geswappt wird, während der reine Swap-Used-Wert aus free nur die aktuelle Auslagerungsgröße zeigt, nicht die Aktivität.

5. Swappiness und Kernel-Parameter richtig einstellen

Der Kernel-Parameter vm.swappiness steuert, wie aggressiv der Kernel Speicherseiten in den Swap auslagert, mit einem Wertebereich von 0 bis 200 seit neueren Kernel-Versionen, klassisch 0 bis 100. Ein hoher Wert wie 60, der bei vielen Distributionen als Standard gesetzt ist, führt dazu, dass der Kernel schon bei moderatem Speicherdruck beginnt, Anwendungsspeicher zugunsten von zusätzlichem Page Cache auszulagern. Für Datenbankserver und Anwendungsserver mit viel RAM ist ein niedrigerer Wert zwischen 1 und 10 meist sinnvoller, weil er Swapping erst bei tatsächlichem Speichermangel zulässt.

Der Wert 0 deaktiviert proaktives Swapping nicht vollständig, sondern lässt den Kernel je nach Version nur noch im Notfall auslagern, um einen Absturz durch Speichermangel zu vermeiden. Änderungen über sysctl vm.swappiness=10 wirken sofort, gehen aber beim Neustart verloren, weshalb dauerhafte Anpassungen in eine Datei unter /etc/sysctl.d/ gehören. Neben swappiness beeinflussen vm.vfs_cache_pressure, das die Aggressivität beim Freigeben von Dentry- und Inode-Caches steuert, sowie vm.dirty_ratio und vm.dirty_background_ratio, die das Verhalten beim Zurückschreiben geänderter Cache-Seiten bestimmen, das Speicherverhalten unter Last.


; /etc/sysctl.d/99-memory-tuning.conf
; Lower swappiness for a database or application server with ample RAM
vm.swappiness = 10

; Reduce eagerness to reclaim dentry and inode caches under memory pressure
vm.vfs_cache_pressure = 50

; Start background writeback earlier to avoid large I/O bursts
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10

; Apply immediately without a reboot:
; sysctl -p /etc/sysctl.d/99-memory-tuning.conf

6. Der OOM-Killer: wann er zuschlägt und wie man ihn steuert

Der Out-Of-Memory-Killer greift erst ein, wenn der Kernel eine Speicheranfrage nicht mehr bedienen kann, weder aus freiem RAM noch durch Auslagerung in den Swap, und wählt dann einen Prozess zur Terminierung aus, um das System vor einem vollständigen Stillstand zu bewahren. Die Auswahl basiert auf dem sogenannten badness score, der aus Speicherverbrauch, Laufzeit und einem manuell einstellbaren oom_score_adj-Wert berechnet wird. Prozesse mit hohem Speicherverbrauch und kurzer Laufzeit werden bevorzugt beendet, während lang laufende Systemprozesse tendenziell verschont bleiben.

Für kritische Dienste wie eine Datenbank lässt sich das Risiko, vom OOM-Killer getroffen zu werden, über echo -1000 in /proc/pid/oom_score_adj deutlich reduzieren, während unwichtige Hilfsprozesse mit einem positiven Wert gezielt zuerst geopfert werden können. dmesg oder journalctl -k zeigen nach einem OOM-Ereignis exakt, welcher Prozess getötet wurde und wie viel Speicher zum Zeitpunkt der Entscheidung belegt war. Wer OOM-Kills häufig sieht, sollte nicht nur den betroffenen Prozess untersuchen, sondern die gesamte Speicherbilanz des Systems, da meist ein anderer Prozess den Speicherdruck ursprünglich verursacht hat.

7. Speicherverbrauch pro Prozess analysieren

Um herauszufinden, welcher Prozess tatsächlich wie viel Speicher verbraucht, reicht ps oder top allein oft nicht aus, weil sie standardmäßig den RSS-Wert zeigen, der gemeinsam genutzten Speicher mehrfach zählt, wenn mehrere Prozesse eine Bibliothek teilen. Das Tool smem berechnet stattdessen den PSS-Wert, der geteilten Speicher anteilig auf alle nutzenden Prozesse verteilt und dadurch ein realistischeres Bild der tatsächlichen Speicherbelastung liefert, besonders bei PHP-FPM-Workern oder mehreren gleichzeitig laufenden Node.js-Prozessen mit gemeinsamen Modulen.

Für die Detailanalyse eines einzelnen Prozesses liefert cat /proc/pid/status Felder wie VmRSS für den tatsächlich im RAM residierenden Anteil, VmSwap für ausgelagerten Speicher desselben Prozesses und VmPeak für den historischen Höchstwert. pmap -x pid schlüsselt den Speicher zusätzlich nach einzelnen Memory-Mappings auf und zeigt, ob eine bestimmte Shared Library oder ein Heap-Segment ungewöhnlich viel Speicher belegt. Diese Werkzeuge zusammen ermöglichen eine präzise Diagnose, statt sich auf die oft irreführende RSS-Spalte aus top zu verlassen.

8. cgroups und Speicherlimits für Container und Dienste

Control Groups, kurz cgroups, ermöglichen es, Speicherlimits pro Prozessgruppe durchzusetzen, unabhängig vom systemweiten Speicherzustand, und bilden die technische Grundlage für Speicherlimits in Docker-Containern und systemd-Diensten. Ein Container mit einem Limit von 512 MB kann niemals mehr als diesen Wert belegen, selbst wenn auf dem Host noch reichlich freier Speicher vorhanden wäre, weil der Kernel die Grenze auf cgroup-Ebene hart durchsetzt und bei Überschreitung den cgroup-eigenen OOM-Killer auslöst, unabhängig vom systemweiten OOM-Killer.

Unter systemd lassen sich vergleichbare Limits direkt in einer Service-Unit über MemoryMax und MemoryHigh setzen, wobei MemoryHigh als weicher Grenzwert wirkt, der den Prozess durch verstärkten Reclaim ausbremst, während MemoryMax als harte Grenze den Prozess bei Überschreitung terminiert. Für Magento- oder PHP-FPM-Deployments in Containern ist es entscheidend, das Speicherlimit realistisch über tatsächlich gemessenen Peak-Verbrauch zu setzen, da ein zu knapp bemessenes Limit den container-eigenen OOM-Killer auslöst, lange bevor der Host selbst unter Speicherdruck gerät.


# docker-compose.yml: hard memory limit enforced via cgroups
services:
  php-fpm:
    image: mironsoft/php-fpm:8.4
    deploy:
      resources:
        limits:
          memory: 1024m
        reservations:
          memory: 512m
    environment:
      PHP_MEMORY_LIMIT: 768M

  mysql:
    image: mysql:8.0
    mem_limit: 4096m
    mem_reservation: 2048m
    # Exceeding mem_limit triggers the cgroup-local OOM killer, not the host OOM killer

9. Monitoring-Tools im Vergleich

Für laufendes Monitoring reicht keines der Einzeltools allein aus: free -h eignet sich für den schnellen Überblick, vmstat 1 für die Beobachtung von Swap-Aktivität in Echtzeit, und /proc/meminfo für die präzise Analyse einzelner Felder in Skripten und Monitoring-Agenten. Prometheus mit dem node_exporter exportiert die relevanten Felder aus /proc/meminfo automatisch als Metriken, sodass sich MemAvailable, SwapFree und Cached über Grafana als Zeitreihe darstellen und mit Alerting-Schwellenwerten versehen lassen, statt sich auf manuelle Stichproben zu verlassen.

Die folgende Übersicht zeigt, wo Fehlinterpretationen typischerweise entstehen und wie die Kennzahlen tatsächlich zu lesen sind.

Kennzahl Fehlinterpretation Korrekte Bedeutung Handlungsempfehlung
used (free -h) Speicher ist fast voll Enthält reclaimable Page Cache available-Spalte statt used prüfen
buff/cache Verschwendeter Speicher Sofort freigebbarer Performance-Cache Nur bei sinkendem available reagieren
Swap Used > 0 System tauscht aktiv, kritisch Kernel hat kalte Seiten ausgelagert si/so in vmstat statt Used-Wert prüfen
MemAvailable Unwichtige Zusatzzeile Realistischste verfügbare Speichermenge Für Alerting-Schwellenwerte verwenden
Hoher RAM-Verbrauch OOM-Killer schlägt sofort zu Killt erst bei nicht bedienbarer Allokation oom_score_adj für kritische Dienste setzen

In der Praxis lohnt sich ein Blick auf mehrere Metriken gemeinsam: Ein Rückgang von MemAvailable über mehrere Tage bei gleichzeitig steigendem Swap-Used deutet auf einen Memory Leak in einer Anwendung hin, während ein einzelner kurzer Ausschlag meist unkritisch ist. Wer diese Zusammenhänge kennt, vermeidet sowohl unnötige Panik bei normalem Cache-Wachstum als auch übersehene echte Speicherprobleme, die sich erst durch die Kombination mehrerer Kennzahlen zeigen.


{
  "alert": "LowMemoryAvailable",
  "expr": "node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes < 0.10",
  "for": "10m",
  "labels": { "severity": "warning" },
  "annotations": {
    "summary": "Available memory below 10 percent for 10 minutes",
    "description": "MemAvailable, not MemFree, is the metric that reflects real memory pressure."
  }
}

Mironsoft

Server-Performance, Kernel-Tuning und Monitoring für Magento-Infrastruktur

Speicherprobleme auf eurem Server zuverlässig diagnostizieren?

Wir analysieren Speicherverhalten, Swap-Konfiguration und cgroup-Limits eurer Magento- und PHP-Infrastruktur, identifizieren echte Engpässe und richten Monitoring ein, das zwischen normalem Cache-Wachstum und echten Problemen unterscheidet.

Speicher-Audit

free, /proc/meminfo und vmstat-Analyse zur Identifikation echter Engpässe

Swap & Kernel-Tuning

swappiness, dirty_ratio und OOM-Score gezielt an die Workload anpassen

Monitoring-Setup

Prometheus/Grafana-Dashboards mit sinnvollen Alerting-Schwellenwerten

10. Zusammenfassung

Die Linux-Speicherverwaltung folgt einem einfachen, aber oft missverstandenen Grundprinzip: ungenutzter Arbeitsspeicher ist verschwendeter Arbeitsspeicher. Der Page Cache füllt freien RAM automatisch mit häufig genutzten Dateiinhalten und gibt ihn ohne Verzögerung frei, sobald Anwendungen ihn benötigen. free -h zeigt deshalb selten viel echten freien Speicher, ohne dass ein Problem vorliegt, solange die Spalte available komfortabel groß bleibt. /proc/meminfo liefert mit MemAvailable, SwapFree und den Cache-Feldern die Rohdaten für eine präzise Einschätzung, die über die Oberfläche von free hinausgeht.

Swap ist ein Overflow-Mechanismus für selten genutzte Speicherseiten, kein primärer Speicher, und moderate Swap-Nutzung ohne aktive si/so-Werte in vmstat ist unbedenklich. vm.swappiness, der OOM-Killer mit oom_score_adj und cgroup-basierte Speicherlimits geben Administratoren gezielte Hebel, um das Speicherverhalten unter Last vorhersehbar zu steuern, statt auf Zufall oder pauschales Cache-Leeren zu vertrauen. Kontinuierliches Monitoring mit mehreren Kennzahlen gemeinsam deckt echte Speicherprobleme zuverlässig auf, lange bevor sie zu Ausfällen führen.

Linux-Speicherverwaltung: RAM, Swap, Cache - Das Wichtigste auf einen Blick

free -h richtig lesen

Nicht used, sondern available betrachten. buff/cache ist reclaimable, kein belegter Speicher.

Page Cache

Kein verschwendeter Speicher, sondern Performance-Booster. Wird bei Bedarf sofort freigegeben.

Swap & Swappiness

Overflow-Mechanismus. si/so in vmstat prüfen, nicht nur den Swap-Used-Wert.

OOM-Killer & cgroups

oom_score_adj und MemoryMax für kontrolliertes Verhalten unter Speicherdruck.

11. FAQ: Linux-Speicherverwaltung verstehen

1Warum zeigt free -h so wenig freien Speicher, obwohl das System nicht überlastet ist?
Der Kernel füllt freien RAM automatisch mit dem Page Cache. Dieser erscheint in buff/cache und wird bei Bedarf sofort wieder freigegeben. Die relevante Kennzahl ist available, nicht free.
2Was ist der Unterschied zwischen used und available bei free?
used enthält reclaimable Cache-Anteile und wirkt höher als der tatsächlich fest belegte Speicher. available schätzt realistisch, was für neue Anwendungen ohne Swapping bereitsteht.
3Was ist der Page Cache und warum ist er kein verschwendeter Speicher?
Er speichert kürzlich gelesene oder geschriebene Dateiinhalte im RAM, um Festplattenzugriffe zu vermeiden, und gibt Speicher sofort frei, sobald er dringender benötigt wird.
4Sollte ich den Page Cache manuell leeren (drop_caches)?
Fast nie in Produktion. Es verschlechtert die Performance kurzfristig, da erneute Festplattenzugriffe nötig werden, bis sich der Cache wieder aufgebaut hat.
5Was bedeutet MemAvailable in /proc/meminfo genau?
Eine realistische Schätzung, wie viel Speicher für neue Anwendungen bereitsteht, inklusive reclaimable Caches. Seit Kernel 3.14 die zuverlässigste Kennzahl für Monitoring.
6Ist Swap-Nutzung ein Zeichen für ein Problem?
Nicht zwingend. Moderate Nutzung ist normal. Kritisch wird es erst bei Thrashing, erkennbar an hohen si/so-Werten in vmstat, nicht am Swap-Used-Wert allein.
7Wie stelle ich vm.swappiness richtig ein?
Für Server mit viel RAM ist ein Wert zwischen 1 und 10 meist sinnvoller als der Standard 60. sysctl vm.swappiness=10 wirkt sofort, dauerhaft gehört es in /etc/sysctl.d/.
8Wann greift der OOM-Killer ein?
Erst wenn weder RAM noch Swap eine Speicheranfrage bedienen können. Auswahl per badness score, beeinflussbar über oom_score_adj.
9Wie finde ich heraus, welcher Prozess wirklich wie viel RAM braucht?
top/ps zeigen RSS, das geteilten Speicher mehrfach zählt. smem berechnet PSS anteilig. Für Details: cat /proc/pid/status mit VmRSS, VmSwap, VmPeak.
10Wie funktionieren Speicherlimits mit cgroups in Docker/systemd?
cgroups setzen Limits pro Prozessgruppe hart durch. In Docker über mem_limit, in systemd über MemoryMax/MemoryHigh. Überschreitung löst den cgroup-eigenen OOM-Killer aus.