Jak zapobiec zawieszaniu się Linuksa, gdy brakuje pamięci?

25

Dzisiaj (przypadkowo) uruchomiłem jakiś program na moim Linux-ie, który szybko zużył dużo pamięci. Mój system zamarł, przestał reagować i dlatego nie byłem w stanie zabić sprawcy.

Jak mogę temu zapobiec w przyszłości? Czy nie może przynajmniej utrzymać responsywnego rdzenia lub czegoś uruchomionego?

johv
źródło
Duplikat zawieszania się systemu, gdy zabraknie mu pamięci , i jest to dobrze znany błąd
Dan Dascalescu

Odpowiedzi:

15

Założę się, że system tak naprawdę nie „zawiesił się” (w tym sensie, że jądro się zawiesiło), ale raczej bardzo nie reagował. Możliwe, że po prostu zmienił się bardzo mocno, powodując, że wydajność interaktywna i przepustowość systemu spadły jak kamień.

Państwo mogłoby wyłączyć swapa, ale to tylko zmienia problem z niską wydajność w procesach OOM zabite (i wszystkie zabawy, które przyczyn), wraz ze spadkiem wydajności z powodu mniej dostępnej pamięci podręcznej dysku.

Alternatywnie, możesz użyć limitów zasobów na proces (zwykle określanych jako rlimiti / lub ulimit), aby wyeliminować możliwość, że pojedynczy proces zajmie absurdalnie dużo pamięci i spowoduje zamianę, ale to po prostu popycha cię do rozrywkowego terytorium procesami, które giną w niewygodne chwile, ponieważ chcieli trochę więcej pamięci, niż system był w stanie im dać.

Jeśli wiedziałeś, że zamierzasz zrobić coś, co może spowodować ogromne zużycie pamięci, prawdopodobnie możesz napisać program opakowujący, który wykonał, mlockall()a następnie uruchomił powłokę; utrzymałoby to w pamięci i byłoby najbliższą rzeczą, aby „zachować responsywny rdzeń”, który prawdopodobnie dostaniesz (ponieważ nie chodzi o to, że procesor jest nadmiernie wykorzystywany, to jest problem).

Osobiście popieram metodę kontroli zasobów „nie rób głupot”. Jeśli masz uprawnienia roota, możesz wyrządzić wszelkiego rodzaju szkody w systemie, a więc robienie wszystkiego , czego nie znasz, jest ryzykownym przedsięwzięciem.

womble
źródło
2
Niestety, „nie rób głupot” nie pomaga użytkownikom, którzy uruchamiają aplikacje wymagające zapamiętywania pamięci, takie jak Chrome (zobacz problemy 134612 , 393395 ).
Dan Dascalescu
1
@DanDascalescu I nie zawsze jest oczywiste, że robisz coś głupiego. Mój komputer zawiesił się innego dnia, ponieważ zmieniłem „UNION” w (skomplikowanym) zapytaniu SQLite na „UNION ALL”.
Michael
Programy o znanych błędach mogą (i powinny) być uruchamiane w konfiguracji ograniczonej pod względem zasobów - ulimitlub nawet w dzisiejszych czasach, jeśli jesteś modnym młodzieńcem, robi to całkiem dobrze. Jeśli wprowadzasz zmiany w zapytaniach w środowisku produkcyjnym bez sprawdzania ich efektów w środowisku niekrytycznym, jest to główny problem.
womble
8

Jak wspomniano powyżej w komentarzu Tronic, możliwe jest wywołanie OOM-killera (poza pamięcią) bezpośrednio przez kombinację klawiszy SysRq- F.

SysRqKlawisz jest zwykle łączony w PrtScklawisz na klawiaturze.

OOM-killer zabija niektóre procesy (-es) i system ponownie reaguje. Bezpośredni dostęp do OOM-Killera może nie być domyślnie włączony, proszę sprawdź to pytanie, aby dowiedzieć się, jak sprawdzić jego status i / lub włączyć.

PS: To mi bardzo pomogło. Zgadzam się z opinią, że jest to najbardziej przydatna porada na temat tego problemu, jeśli jest spowodowany przez Chrome lub inne chciwe oprogramowanie pamięci. Ale musisz pamiętać, że zabójca OOM może zabić jakiś naprawdę ważny proces, używaj go ostrożnie.

Arkemlar
źródło
0

Jeśli masz ochotę ponownie skompilować jądro, możesz wypróbować łatkę z EDITsekcji tego pytania: /programming//q/52067753/10239615
Nie usuwa Active(file)stron podczas wysokiego ciśnienia pamięci, a zatem pozwala OOM-killerowi uruchamiać się niemal natychmiast, ponieważ jądro nie musi już spędzać minut ciągłego ponownego odczytu z dysku wszystkich wykonywalnych stron kodowych każdego procesu powodującego zawieszenie systemu operacyjnego.


źródło
-1

Jest to coś szczególnie trudnego do uniknięcia. To dlatego, że jądro zaczyna się zamieniać. Jednym z rozwiązań jest wyłączenie zamiany. Kiedy w systemie zabraknie pamięci, zamiast rozpocząć zamianę, jądro zabije niektóre procesy; zwykle wybiera właściwy proces do zabicia, ale i tak lepiej zabić proces losowy, niż mieć system nieodpowiadający.

Może to być szczególnie dobre rozwiązanie dla serwerów, ponieważ serwery często mają wystarczającą ilość pamięci RAM, a kiedy zaczynają używać przestrzeni wymiany, oznacza to, że coś jest nie tak. Jednak komputery stacjonarne zwykle potrzebują przestrzeni wymiany, więc myślę, że nie ma dobrego rozwiązania dla komputerów stacjonarnych. Często wyłączam przestrzeń wymiany na serwerach, szczególnie gdy istnieje podejrzenie wycieku pamięci.

Antonis Christofides
źródło
4
Wyłączenie wymiany w dowolnym systemie jest złym pomysłem, ponieważ nie pozwala na zamianę nieużywanych stron i wolne miejsce na pamięć podręczną dysku. Jest to szczególnie prawdziwe, gdy występuje przeciek pamięci.
womble
2
A po wymianie system nadal może zwolnić z powodu stronicowania. Będzie tylko szaleńczo stronicować czyste strony zamiast brudnych. (Ponieważ bez zamiany nigdy nie może eksmitować brudnej strony, zawsze będzie musiał eksmitować czyste strony.)
David Schwartz
Mam serwer, który ma wyciek pamięci. Za pierwszym razem musiałem nacisnąć przycisk resetowania, ponieważ serwer przestał reagować. Ale teraz, kiedy wyłączyłem swap, serwer po prostu zabija dziecko Apache, jeśli staje się zbyt duże (jest to zabezpieczenie oprócz MaxRequestsPerChild). W rezultacie serwer działa bez problemu. I tak nie ma wielu nieużywanych stron, a na pewno nie szalenie stronicuje czystych stron.
Antonis Christofides,
@AntonisChristofides: Nie jestem pewien, co według ciebie jest lekcja na wynos. Twoje rozwiązanie jest z pewnością złe, ponieważ obniża wydajność z powodu niemożności eksmisji rzadko używanych brudnych stron z pamięci fizycznej, nie rozwiązało podstawowego problemu i ryzykujesz, że zabójca OOM może zabić krytyczny proces. Zdarzyło się, że nie spotkałeś się z konkretnym zagrożeniem, o którym ostrzegałem, ale nadal jesteś zagrożony, ponieważ nie masz zamiany.
David Schwartz
8
Z zamiennikiem lub bez niego nadal zawiesza się, zanim zabójca OOM zostanie uruchomiony automatycznie. To jest naprawdę błąd jądra, który powinien zostać naprawiony (tj. Uruchom OOM killer wcześniej, zanim zrzucisz całą pamięć podręczną dysku). Niestety twórcy jądra i wielu innych ludzi nie dostrzega problemu. Typowe sugestie, takie jak wyłączanie / włączanie zamiany, kupowanie większej ilości pamięci RAM, uruchamianie mniejszej liczby procesów, ustawianie limitów itp. Nie rozwiązują podstawowego problemu polegającego na tym, że niska pamięć jądra wysysa kulki wielbłąda. Tymczasem sugeruję ręczne uruchomienie OOM Killer (SysRq-F), gdy system zawiesza się, ponieważ spowoduje to szybsze odzyskiwanie.
Tronic,