OOM Killer nie działa?

41

Z tego co rozumiem, kiedy system jest blisko i nie ma wolnej pamięci, jądro powinno zacząć zabijać procesy, aby odzyskać trochę pamięci. Ale w moim systemie tak się wcale nie dzieje.

Załóżmy, że prosty skrypt, który po prostu przydziela znacznie więcej pamięci niż dostępna w systemie (na przykład tablica zawierająca miliony ciągów znaków). Jeśli uruchomię taki skrypt (jako zwykły użytkownik), po prostu pobierze całą pamięć, aż system całkowicie się zawiesi (działa tylko SysRQ REISUB).

Dziwne jest to, że gdy komputer zawiesza się, dioda dysku twardego włącza się i pozostaje tak do momentu ponownego uruchomienia komputera, czy mam zamontowaną partycję wymiany, czy nie!

Więc moje pytania to:

  1. Czy to zachowanie jest normalne? Dziwne, że aplikacja wykonana jako zwykły użytkownik może po prostu zawiesić system w ten sposób ...
  2. Czy jest jakiś sposób, aby zmusić Ubuntu do automatycznego zabijania tych aplikacji, gdy mają za dużo (lub najwięcej) pamięci?

Dodatkowe informacje

  • Ubuntu 12.04.3
  • Jądro 3.5.0-44
  • RAM: ~ 3,7 GB z 4 GB (współdzielone z kartą graficzną). *

    $ tail -n+1 /proc/sys/vm/overcommit_*
    ==> /proc/sys/vm/overcommit_memory <==
    0
    
    ==> /proc/sys/vm/overcommit_ratio <==
    50
    
    $ cat /proc/swaps
    Filename                Type        Size    Used    Priority
    /dev/dm-1                               partition   4194300 344696  -1
    
Salem
źródło
Nie jestem pewien, dlaczego to nie działa. Spróbuj tail -n+1 /proc/sys/vm/overcommit_*i dodaj wynik. Zobacz także tutaj: Jak skonfigurować oom-
killera
Co się dzieje z twoją przestrzenią wymiany? Czy możesz opublikować jakieś dane wyjściowe vmstat, takie jak #vmstat 1 100, czy coś takiego? a także pokaż nam cat / etc / fstab Co powinno się zdarzyć przy pewnym zużyciu pamięci, powinieneś zacząć pisać do zamiany. Procesy zabijania nie powinny mieć miejsca, dopóki pamięć i przestrzeń wymiany nie zostaną „zapełnione”.
j0h
spróbuj także #swapon -a
j0h
@ j0h Z wymianą wydaje się działać dobrze (po pewnym czasie proces zawiesił się z czymś podobnym Allocation failed). Ale bez zamiany po prostu zawiesza komputer. Ma to działać w ten sposób (zabijać tylko przy użyciu wymiany)?
Salem
2
Z SysRq możesz także wywoływać OOM (SysRq + F iirc)
Lekensteyn

Odpowiedzi:

36

Z oficjalnej /proc/sys/vm/*dokumentacji :

oom_kill_allocating_task

To włącza lub wyłącza zabijanie zadania wyzwalającego OOM w sytuacjach braku pamięci.

Jeśli ta wartość zostanie ustawiona na zero, zabójca OOM przejrzy całą listę zadań i wybierze zadanie oparte na heurystyce do zabicia. Zwykle wybiera to nieuczciwe zadanie zapamiętywania pamięci, które zwalnia dużą ilość pamięci po zabiciu.

Jeśli jest ustawiona na niezerową, zabójca OOM po prostu zabija zadanie, które wywołało stan braku pamięci. Pozwala to uniknąć kosztownego skanowania listy zadań.

Jeśli wybrano opcję panic_on_oom, ma ona pierwszeństwo przed dowolną wartością użytą w zadaniu oom_kill_allocating_task.

Wartość domyślna to 0.

Aby podsumować, podczas ustawiania oom_kill_allocating_tasksię 1, zamiast skanowanie systemu szuka procesów zabijać, który jest kosztowny i powolny zadanie, jądro będzie po prostu zabić proces powodujący, że system wyjść z pamięci.

Z moich własnych doświadczeń wynika, że ​​po uruchomieniu OOM jądro nie ma już wystarczającej „siły” do wykonania takiego skanowania, dzięki czemu system jest całkowicie bezużyteczny.

Bardziej oczywiste byłoby po prostu zabicie zadania, które spowodowało problem, więc nie rozumiem, dlaczego jest ustawione 0domyślnie.

Aby przetestować, możesz po prostu napisać w odpowiednim pseudo-pliku /proc/sys/vm/, który zostanie cofnięty przy następnym uruchomieniu:

echo 1 | sudo tee /proc/sys/vm/oom_kill_allocating_task

Dla stałej poprawki, napisać następujące do /etc/sysctl.conflub do nowego pod pliku /etc/sysctl.d/, z .confrozszerzeniem ( /etc/sysctl.d/local.confna przykład):

vm.oom_kill_allocating_task = 1
Teresa e Junior
źródło
2
Czy zawsze był ustawiony na 0 w Ubuntu? Bo pamiętam, że kiedyś zabijało automatycznie, ale od kilku wersji przestało to robić.
skerit
1
@skerit Nie wiem tak naprawdę, ale w jądrach używanych w 2010 roku (0 Debian, Liquorix i GRML) ustawiono na 0.
Teresa e Junior
„Ponadto bardziej oczywiste byłoby zabicie zadania, które spowodowało problem, więc nie rozumiem, dlaczego jest ono ustawione 0domyślnie”. - ponieważ proces, który zażądał pamięci, niekoniecznie musi być tym, który „spowodował problem”. Jeśli proces A zajmie 99% pamięci systemu, ale proces B, który wykorzystuje 0,9%, zdarza się być tym, który uruchamia zabójcę OOM przez nieszczęście, B nie „powoduje problemu” i nie ma sensu kill B. Posiadanie tego, ponieważ polityka grozi całkowitym bezproblemowym zabiciem procesów o niskiej pamięci przez przypadek z powodu niekontrolowanego użycia pamięci przez inny proces.
Mark Amery
1
@ MarkAmery Prawdziwy problem polega na tym, że Linux zamiast zabijać potrzebny proces, zaczyna rzucać się jak opóźnienie, nawet jeśli vm.admin_reserve_kbyteszostanie zwiększony do, powiedzmy, 128 MB . Ustawienie vm.oom_kill_allocating_task = 1wydaje się łagodzić problem, tak naprawdę go nie rozwiązuje (a Ubuntu już domyślnie zajmuje się bombami widełkowymi).
Teresa e Junior,
1
Może bardziej eleganckisudo sysctl -w vm.oom_kill_allocating_task=1
Pablo A
9

Aktualizacja: Błąd został naprawiony.

Odpowiedź Teresy wystarczy, aby obejść problem i jest dobra.

Dodatkowo, zgłosiłem raport o błędzie, ponieważ jest to zdecydowanie zepsute zachowanie.

int_ua
źródło
Nie wiem, dlaczego zostałeś przegłosowany, ale dla mnie to też brzmi jak błąd jądra. Zepsułem dzisiaj duży serwer uniwersytecki i zabiłem kilka procesów, które działały przez tygodnie ... Dziękuję za zgłoszenie tego błędu!
shapecatcher
7
Być może zostało to naprawione w 2014 roku, w 2018 roku (i 18.04) zabójca OOM po raz kolejny nic nie robi.
skerit
0

Możesz spróbować wcześnie , zabójca OOM, który działa w przestrzeni użytkownika i próbuje zabić największy proces w sytuacji OOM.

qwr
źródło
-1

Przede wszystkim polecam aktualizację do 13.10 (czysta instalacja, zapisz dane).

Jeśli nie chcesz aktualizować, zmień vm.swappiness na 10 i jeśli napotkasz problemy z ram, zainstaluj ZRAM.

Brask
źródło
2
Nie byłem tym, który cię ocenił, ale ogólnie obniżenie vm.swappinesspowoduje więcej szkody niż pożytku, a nawet więcej w systemach cierpiących na problemy z niską pamięcią.
Teresa e Junior
Nie wtedy, gdy najpierw kompresujesz RAM, a następnie unikniesz użycia dysku, który jest znacznie wolniejszy i może powodować zawieszanie się komputera.
Brask
Teoretycznie ZRAM jest fajną rzeczą, ale wymaga dużej mocy obliczeniowej i generalnie nie jest wart swojej ceny. Pamięć jest ogólnie znacznie tańsza niż elektryczność. A na laptopie, gdzie uaktualnienie pamięci RAM jest droższe, użycie procesora jest w większości niepożądane.
Teresa e Junior
To, o co prosi, to mieć bardziej stabilny system ZRAM, a zmiana swapowania sprawi, że jego system będzie zużywał więcej zasobów procesora tak, ale to, że jest on ograniczony i ma błędy w pamięci, chce naprawić problem, a nie lekcję teorii tego, co dzieje się po zainstalowaniu ZRAM.
Brask
Z jego pytania jasno wynika, że ​​może napisać niewłaściwy skrypt, który zjada więcej niż powinien (a ja już to zrobiłem). W takiej sytuacji możesz zobaczyć, jak skrypt chwyta gigabajty pamięci RAM w ciągu kilku sekund, a ZRAM nie przyjdzie na ratunek, ponieważ skrypt nigdy nie będzie wystarczający.
Teresa e Junior