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.
Inhaltsverzeichnis
- 1. Warum free -h zunächst alarmierend wirkt
- 2. Der Page Cache: RAM sinnvoll nutzen statt brachliegen zu lassen
- 3. /proc/meminfo: die Datenquelle hinter free
- 4. Swap: Overflow-Speicher, nicht primärer Arbeitsspeicher
- 5. Swappiness und Kernel-Parameter richtig einstellen
- 6. Der OOM-Killer: wann er zuschlägt und wie man ihn steuert
- 7. Speicherverbrauch pro Prozess analysieren
- 8. cgroups und Speicherlimits für Container und Dienste
- 9. Monitoring-Tools im Vergleich
- 10. Zusammenfassung
- 11. FAQ
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.