OOM Killer

Mechanizm jądra, który przy wyczerpaniu pamięci RAM zabija wybrane procesy, by uratować system. Wybiera ofiary na podstawie zużycia pamięci i przyznanej punktacji.

OOM Killer (Out Of Memory Killer) to mechanizm jądra Linux, który wkracza do akcji, gdy system fizycznie nie ma już wolnej pamięci RAM ani miejsca w swapie. Zamiast pozwolić całej maszynie zamarznąć w martwym uścisku, jądro wybiera jeden proces i bezceremonialnie go zabija sygnałem SIGKILL, żeby odzyskać pamięć i utrzymać system przy życiu. Brutalne, ale skuteczne.

Jak to działa

Linux domyślnie stosuje overcommit, czyli obiecuje procesom więcej pamięci, niż realnie posiada — bo i tak większość aplikacji nie używa wszystkiego, co zarezerwowała. Problem zaczyna się, gdy procesy naprawdę chcą skorzystać z tych obietnic naraz. Wtedy fizyczna pamięć się kończy, a jądro nie ma jak spełnić żądania alokacji.

W tym momencie odpala się OOM Killer. Każdemu procesowi przypisywany jest oom_score — im wyższy, tym większy kandydat na ofiarę. Wynik zależy głównie od zużycia pamięci (proces żrący najwięcej RAM-u jest pierwszy w kolejce), ale możesz go ręcznie korygować przez oom_score_adj w zakresie od -1000 (chroń za wszelką cenę) do 1000 (zabij w pierwszej kolejności). Wartość -1000 praktycznie wyłącza proces z puli celów.

Przykład z praktyki

Twój kontener z aplikacją Node albo bazą danych nagle znika, a restart nie ma logów aplikacji wyjaśniających dlaczego. Pierwszy ruch: sprawdź jądro.

  • dmesg | grep -i oom — zobaczysz wpisy w stylu Out of memory: Killed process 12345 (mysqld).
  • journalctl -k | grep -i "killed process" — to samo na systemach z systemd.
  • cat /proc//oom_score — podejrzysz aktualny scoring żywego procesu.

Chcesz uchronić krytyczny proces? Ustaw mu echo -1000 > /proc//oom_score_adj. Tylko świadomie — bo jeśli ochronisz złą rzecz, ofiarą padnie coś jeszcze ważniejszego.

Częste błędy i mity

„Proces sam się wykrzaczył” — niekoniecznie. Jeśli aplikacja ginie bez śladu w swoich logach, a w dmesg jest wpis o OOM, to jądro ją ubiło, nie ona sama. „OOM Killer zabija proces, który zżarł pamięć” — zwykle tak, ale nie zawsze: ofiarą może paść zupełnie inny proces, jeśli ma wyższy score. Wyłączanie overcommitu na czuja przez vm.overcommit_memory to też pułapka — łatwiej wtedy o odrzucone alokacje, niż się spodziewasz. W kontenerach pamiętaj, że limit pamięci cgroup ma własny OOM Killer, niezależny od tego globalnego.

Pojęcia powiązane: overcommit, swap, cgroups i limity pamięci w Dockerze/Kubernetes (OOMKilled), sygnał SIGKILL, vm.overcommit_memory, plik /proc//oom_score_adj oraz dmesg jako pierwsze źródło prawdy przy diagnozie.