Unikaj porzucania aplikacji braku pamięci w systemie Linux

34

Zauważyłem, że czasami w moim Linux-ie zabrakło pamięci i zaczyna on rozrywać losowe procesy, aby sobie z tym poradzić.

Jestem ciekaw, co administratorzy robią, aby tego uniknąć? Czy jest to jedyne realne rozwiązanie zwiększające ilość pamięci (czy sama zamiana pomoże?), Czy też są lepsze sposoby na skonfigurowanie skrzynki z oprogramowaniem, aby tego uniknąć? (tj. kwoty lub niektóre takie?).

Eddie Parker
źródło
Znalazłem odpowiedź tutaj: serverfault.com/questions/362589 / ... Odpowiedź Patricka jest bardzo pouczająca
Amaury

Odpowiedzi:

44

Domyślnie Linux ma nieco uszkodzoną mózg koncepcję zarządzania pamięcią: pozwala ci przydzielić więcej pamięci niż twój system, a następnie losowo strzela procesowi w głowę, gdy wpada w kłopoty. (Rzeczywista semantyka zabijania jest bardziej złożona - Google „Linux OOM Killer” dla wielu szczegółów i argumentów na temat tego, czy jest to dobra, czy zła rzecz).


Aby przywrócić odrobinę zdrowia psychicznego do zarządzania pamięcią:

  1. Wyłącz OOM Killer ( vm.oom-kill = 0wstaw w /etc/sysctl.conf)
  2. Wyłącz overcommit pamięci (wstaw do pliku vm.overcommit_memory = 2/etc/sysctl.conf)
    Zauważ, że jest to wartość trójdzielna: 0 = „oszacuj, jeśli mamy wystarczającą ilość pamięci RAM”, 1 = „Zawsze mów tak”, 2 = „powiedz nie, jeśli nie mamy mieć pamięć ”)

Te ustawienia sprawią, że Linux będzie się zachowywał w tradycyjny sposób (jeśli proces zażąda więcej pamięci niż jest dostępna, malloc () zawiedzie i oczekuje się, że proces żądający pamięci poradzi sobie z tym niepowodzeniem).

Uruchom ponownie komputer, aby go ponownie załadować /etc/sysctl.conf, lub użyj procsystemu plików, aby włączyć od razu, bez ponownego uruchamiania:

echo 2 > /proc/sys/vm/overcommit_memory 
voretaq7
źródło
11
To nie Linux jest uszkodzony, ale programiści, którzy przydzielają pamięć, nigdy jej nie używają. Maszyny wirtualne Java są z tym znane. Ja, jako administrator zarządzający serwerami z aplikacjami Java, nie przeżyłbym ani sekundy bez nadmiernego zaangażowania.
Aleksandar Ivanisevic
11
Programiści Java nie przydzielają nieużywanej pamięci, w java nie ma malloc. Myślę, że mylisz to z ustawieniami JVM, takimi jak -Xms. W każdym razie zwiększenie wielkości pamięci wirtualnej poprzez dodanie przestrzeni wymiany jest znacznie bezpieczniejszym rozwiązaniem niż nadmierne zaangażowanie.
jlliagre
5
Pamiętaj, że to rozwiązanie nie powstrzyma systemu przed wyczerpaniem się pamięci lub procesami zabijania. Spowoduje to tylko powrót do tradycyjnego zachowania uniksowego, w którym jeśli jeden proces zje całą pamięć, następny, który próbuje Malloc, nie dostanie żadnego (i najprawdopodobniej ulegnie awarii). Jeśli masz pecha, że ​​następnym procesem jest init (lub coś innego, co jest krytyczne), którego OOM Killer zazwyczaj unika.
pehrs
8
jlliagre, powiedziałem Java VMs (Virtual Machines), a nie programy Java, chociaż z administracyjnego punktu widzenia jest to samo :)
Aleksandar Ivanisevic
8
Być może warto tutaj wspomnieć, że dodanie powyższej opcji /etc/sysctl.confprawdopodobnie nastąpi dopiero przy następnym ponownym uruchomieniu; jeśli chcesz teraz wprowadzić zmiany , powinieneś użyć sysctlpolecenia z uprawnieniami roota, np.sudo sysctl vm.overcommit_memory=2
nickgrim
3

Krótką odpowiedzią dla serwera jest zakup i instalacja większej ilości pamięci RAM.

Serwer, który rutynowo doświadczał błędów OOM (brak pamięci), a następnie oprócz opcji overcommit sysctl menedżera VM (pamięci wirtualnej) w jądrach Linuksa, nie jest to dobra rzecz.

Zwiększenie ilości wymiany (pamięci wirtualnej, która została stronicowana na dysk przez menedżera pamięci jądra) pomoże, jeśli bieżące wartości są niskie, a użycie wiąże się z wieloma zadaniami dla każdej tak dużej ilości pamięci, a nie z jedną lub kilkoma przetwarza każde żądanie dużej ilości całkowitej dostępnej pamięci wirtualnej (RAM + swap).

W przypadku wielu aplikacji, które przydzielają więcej niż dwa razy (2x) ilość pamięci RAM jako swap, zmniejsza się zwrot z poprawy. W niektórych dużych symulacjach obliczeniowych może to być dopuszczalne, jeśli spowolnienie prędkości jest możliwe do wytrzymania.

Pamięć RAM (ECC lub nie) jest dość przystępna dla niewielkich ilości, np. 4-16 GB, muszę przyznać, że od dawna nie doświadczyłam tego problemu.

Podstawy spojrzenia na zużycie pamięci, w tym użycie freei topposortowane według zużycia pamięci, jako dwóch najczęstszych szybkich ocen wzorców wykorzystania pamięci. Upewnij się więc, że rozumiesz przynajmniej znaczenie każdego pola w danych wyjściowych tych poleceń.

Bez specyfiki aplikacji (np. Bazy danych, serwera usług sieciowych, przetwarzania wideo w czasie rzeczywistym) i użycia serwera (niewielu zaawansowanych użytkowników, 100–1000 połączeń użytkownik / klient), nie mogę wymyślić żadnych ogólnych zaleceń dotyczących radzenia sobie z problem OOM.

Mctylr
źródło
3

Zwiększenie ilości pamięci fizycznej może nie być skuteczną reakcją we wszystkich okolicznościach.

Jednym ze sposobów sprawdzenia tego jest polecenie „atop”. W szczególności te dwie linie.

To jest serwer, kiedy był zdrowy:

MEM | tot   23.7G | free   10.0G | cache   3.9G | buff  185.4M | slab  207.8M |
SWP | tot    5.7G | free    5.7G |              | vmcom  28.1G | vmlim  27.0G |

Gdy działał on słabo (i zanim zmieniliśmy pamięć nadmierną komendę z 50 na 90, widzieliśmy zachowanie z vmcom działającym dobrze powyżej 50G, oom-killer wysadzający co kilka sekund, a obciążenie wciąż odbijało się radykalnie z powodu procesów potomnych NFSd i nieustannie tworzone.

Niedawno zduplikowaliśmy przypadki, w których wieloużytkownikowe serwery terminali Linux masowo nadmiernie przydzielają alokację pamięci wirtualnej, ale bardzo niewiele żądanych stron jest faktycznie zużywanych.

Chociaż nie zaleca się podążania tą dokładną trasą, zmieniliśmy pamięć overcommit z domyślnych 50 na 90, co złagodziło część problemu. Ostatecznie musieliśmy przenieść wszystkich użytkowników na inny serwer terminali i zrestartować, aby zobaczyć pełną korzyść.

Magellan
źródło
2

Możesz użyć ulimit, aby zmniejszyć ilość pamięci, którą proces może zająć, zanim zostanie zabity. Jest to bardzo przydatne, jeśli twoim problemem jest jeden lub kilka procesów ucieczki, które powodują awarię serwera.

Jeśli masz problem z tym, że po prostu nie masz wystarczającej ilości pamięci do uruchomienia potrzebnych usług, istnieją tylko trzy rozwiązania:

  1. Zmniejsz pamięć używaną przez twoje usługi, ograniczając pamięć podręczną i tym podobne

  2. Utwórz większy obszar wymiany. Będzie cię to kosztować pod względem wydajności, ale może dać ci trochę czasu.

  3. Kup więcej pamięci

pehrs
źródło
0

Miałem podobny problem związany z tym błędem i rozwiązaniem było użycie starszego / nowszego (naprawionego) jądra.

Jednak w tym czasie nie mogłem ponownie uruchomić mojego komputera, więc jakimś brzydkim obejściem było zalogowanie się jako root i wyczyszczenie pamięci podręcznej systemu za pomocą tego polecenia:

echo 3 > /proc/sys/vm/drop_caches
Krzysztof Dryja
źródło
-5

@ voretaq7 linux nie ma uszkodzonej przez mózg koncepcji zarządzania pamięcią, domyślnie vm.overcommit_ratio ma wartość 0,

0       -   Heuristic overcommit handling. Obvious overcommits of
            address space are refused. Used for a typical system. It
            ensures a seriously wild allocation fails while allowing
            overcommit to reduce swap usage.  root is allowed to
            allocate slightly more memory in this mode. This is the
            default.

W ten sposób, jeśli masz 4 GB pamięci RAM i próbujesz przydzielić 4,2 GB za pomocą malloc pamięci wirtualnej, alokacja się nie powiedzie.

Z vm.overcommit_ratio = 1

            1    -   Always overcommit. Appropriate for some scientific
            applications. Classic example is code using sparse arrays
            and just relying on the virtual memory consisting almost
            entirely of zero pages.

Z vm.overcommit_ratio = 2

           2    -   Don't overcommit. The total address space commit
            for the system is not permitted to exceed swap + a
            configurable percentage (default is 50) of physical RAM.
            Depending on the percentage you use, in most situations
            this means a process will not be killed while accessing
            pages but will receive errors on memory allocation as
            appropriate.

            Useful for applications that want to guarantee their
            memory allocations will be available in the future
            without having to initialize every page.

Więc domyślnie linux nie przesadza, jeśli twoja aplikacja ma więcej pamięci niż masz, być może twój kod jest wadliwy

c4f4t0r
źródło
2
Zaprzeczyłeś sobie tutaj. Na górze mówisz „domyślnie vm.overcommit_ratio wynosi 0”, a na dole mówisz „domyślnie linux nie przesadza”. Gdyby to ostatnie było prawdą, vm.overcommit_ratio domyślnie wynosiłby 2!
Michael Hampton
vm.overcommit_ratio = 0, malloc nie Alloc więcej pamięci niż fizycznej pamięci RAM, więc dla mnie to znaczy nie overcommitu, overcommitu jest, kiedy można przeznaczyć więcej niż wirtualny fizycznej pamięci RAM
c4f4t0r
2
Tak, źle zrozumiałeś.
Michael Hampton
źle zrozumiałeś, domyślnie 0, nie przydzielasz, aby przydzielić więcej pamięci wirtualnej niż ram, a 2 nie przekracza dopuszczenia vm.overcommit_ratio + swap space, więc jeśli źle zrozumiałem, powiedz mi
c4f4t0r
2
Oczywiście. „Oczywiste nadmierne zobowiązania” są odrzucane. Reszta mija. Musisz przeczytać uważniej.
Michael Hampton