Mit dem Signal beginnen, nicht mit der Vermutung
Nach Linux-Konvention wird Signal 9 (SIGKILL) als 128 + 9 = 137 gemeldet. Ein OOM-Killer kann dieses Signal senden – ebenso docker kill, ein Watchdog oder ein Bediener.
Docker-Zustand sichern
Bei einem Restart-Loop die Policy am bestehenden Container deaktivieren und den nächsten natürlichen Fehler abwarten. So überschreibt kein manueller Stop den Zustand:
mc_container_id="$(docker compose ps -a -q mc)"
docker update --restart=no "$mc_container_id"
docker wait "$mc_container_id"
docker inspect "$mc_container_id" --format 'exit={{.State.ExitCode}} oom={{.State.OOMKilled}} error={{json .State.Error}} restarts={{.RestartCount}}'
docker compose logs --tail=250 --timestamps mc
exit=137 oom=true: starker Beleg für einen Docker-/cgroup-OOM-Killexit=137 oom=false: vor einer RAM-Erhöhung nach einer anderen SIGKILL-Quelle suchen- JVM-
OutOfMemoryErrorbei anderem Exit-Code: Java-Heap ist intern erschöpft, ohne zwingenden Docker-OOM-Kill
Container- und Hostlimits prüfen
docker compose config
docker inspect "$mc_container_id" --format 'limit={{.HostConfig.Memory}} swap={{.HostConfig.MemorySwap}}'
docker stats --no-stream "$mc_container_id"
docker info
journalctl -k --since "-30 min" | grep -Ei 'out of memory|oom-kill|killed process'
Unter cgroup v2 liefert der laufende Container zusätzliche Zähler:
docker compose exec mc sh -c 'cat /sys/fs/cgroup/memory.events 2>/dev/null'
Ein steigendes oom_kill bestätigt Kills in dieser cgroup.
Die zwei Speichergrenzen verstehen
MEMORY, INIT_MEMORY und MAX_MEMORY des Images betreffen nur den Java-Heap. mem_limit begrenzt den gesamten Container, also zusätzlich:
- Metaspace und JIT-Codecache
- native Loader-/Kompressionsspeicher
- Thread-Stacks
- direkte Netzwerkpuffer
- Image-Helper und weitere Prozesse
Die itzg-Dokumentation empfiehlt als allgemeine Basis etwa 25 % Reserve über dem Heap.
Limit mit echter Reserve setzen
services:
mc:
image: itzg/minecraft-server:java25
restart: unless-stopped
environment:
EULA: "TRUE"
TYPE: PAPER
VERSION: "26.1.2"
MEMORY: 6G
mem_limit: 8g
volumes:
- ./data:/data
Das ist ein Startverhältnis, keine Garantie für jedes Modpack. Der Host braucht zusätzlich RAM für Linux, Docker, Dateicache, Backups und andere Services. Ein Host mit 8 GB ist kein sinnvoller Platz für ein 8-GB-Containerlimit.
Für JVM-Zuteilungsfehler vorübergehend:
environment:
DEBUG_MEMORY: "TRUE"
Nach Beweislage korrigieren
Containerlimit liegt zu nah am Heap
Reduziere MEMORY oder erhöhe mem_limit mit verbleibender Hostreserve. Wende die Änderung mit docker compose up -d mc an, nicht mit einem einfachen Restart.
Der Host ist erschöpft
Stoppe konkurrierende Last, reduziere Minecraft oder nutze mehr physischen RAM. Swap kann kurz puffern, ist aber deutlich langsamer.
OOMKilled ist false
Suche in Deployments, Automatisierung und Bedienhistorie nach einem Kill:
docker events --since 30m --filter container="$mc_container_id"
Prüfe auch Stop-Timeouts: Nach Ablauf der Grace Period kann Docker SIGKILL senden.
Speicher wächst weiter
Erhöhe Limits nicht endlos. Reproduziere ohne neue Plugins/Mods, prüfe Pack-Anforderungen und profiliere. Heap-Druck, native Leaks und zu viele Chunks brauchen unterschiedliche Lösungen.
Änderung unter echter Last prüfen
docker compose up -d mc
docker compose logs -f mc
docker stats --no-stream "$(docker compose ps -q mc)"
docker inspect "$(docker compose ps -q mc)" --format 'oom={{.State.OOMKilled}} restarts={{.RestartCount}}'
Teste die Last, bei der es zuvor scheiterte: Pack-Initialisierung, Weltgenerierung, Spieler-Peak oder Backup-Kompression. Ein leerer Idle-Start genügt nicht.
Gefährliche Abkürzungen vermeiden
- Heap nicht gleich dem harten Containerlimit setzen
- OOM-Killer nicht deaktivieren
- Container nicht den gesamten Host-RAM geben
- Exit 137 nicht automatisch als OOM behandeln
- wiederholte OOMs nicht hinter unbegrenzten Restarts verstecken
Nächste Schritte
- Bei anderer Schleifenursache den Restart-Loop-Guide nutzen.
- Pack-Anforderungen mit dem CurseForge-Runbook abgleichen.
- Bei stabilem Speicher, aber langsamen Ticks TPS, MSPT und Lag untersuchen.