Jeśli proces wymaga dużej ilości pamięci, system przenosi wszystkie inne procesy do pliku wymiany. W tym wydaje się, niezbędne procesy, takie jak serwer X11 lub terminal.
Jeśli więc proces nadal alokuje bez ograniczeń, wszystko przestaje odpowiadać, dopóki ten proces nie zostanie zabity przez zabójcę OOM. Mój laptop wydaje się szczególnie rozsądny i reaguje wyjątkowo źle. Właśnie spędziłem CAŁĄ GODZINĘ, czekając na zakończenie procesu, podczas którego nawet kursor myszy nie może zostać poruszony.
Jak można tego uniknąć?
1) Wyłącz swap => Często uruchamiam wiele procesów, które następnie stają się nieaktywne. Nieaktywne należy przenieść na wymianę.
2) Uzyskaj dysk SSD => za drogi
3) ustaw maksymalną pamięć ulimit =>, ale wtedy się nie powiedzie, gdy program potrzebuje rezonansowej, dużej ilości pamięci. problemem nie jest to, że zużywa za dużo, ale że tłumi inne procesy
4) przechowuj ważne programy (X11, bash, kill, top, ...) w pamięci i nigdy nie zamieniaj tych => czy można to zrobić? w jaki sposób? może zamieniasz tylko duże programy?
5)
Odpowiedzi:
TL; DR
Krótki tymczasowy / odpowiedź
ulimit -v
, a może ustaw sztywny lub miękki limit za pomocąas
opcji wlimits.conf
). Kiedyś działało to wystarczająco dobrze, ale dzięki wprowadzeniu WebKitgigacage
wiele aplikacji gnome oczekuje teraz nieograniczonej przestrzeni adresowej i nie działa!sysctl vm.overcommit_memory
,sysctl vm.overcommit_ratio
ale takie podejście nie działa dla mnie.Znalazłem też:
Rozwiązanie długoterminowe
poczekaj i mam nadzieję, że niektóre łatki wcześniejsze wejdą do stabilnych jąder dystrybucji. Miej również nadzieję, że dostawcy dystrybucji lepiej dostroją ustawienia domyślne jądra i lepiej wykorzystają grupy systemowe, aby priorytetowo reagować na GUI w wydaniach na komputery stacjonarne.
Niektóre interesujące łatki:
Zatem winny jest nie tylko zły kod przestrzeni użytkownika i konfiguracja / ustawienia domyślne dystrybucji - jądro może to lepiej obsłużyć.
Komentarze do rozważanych już opcji
Zalecane jest zapewnienie przynajmniej małej partycji wymiany ( czy naprawdę potrzebujemy wymiany w nowoczesnych systemach? ). Wyłączenie zamiany nie tylko zapobiega zamianie nieużywanych stron, ale może również wpływać na domyślną heurystyczną strategię nadmiernego zatwierdzania pamięci przez jądro w celu alokacji pamięci ( co oznacza heurystyka w Overcommit_memory = 0? ), Ponieważ ta heurystyka ma znaczenie dla stron wymiany. Bez zamiany overcommit nadal prawdopodobnie działa w trybie heurystycznym (0) lub zawsze (1), ale połączenie strategii no swap i nigdy (2) strategii overcommit jest prawdopodobnie okropnym pomysłem. W większości przypadków żadna zamiana prawdopodobnie nie zaszkodzi wydajności.
Na przykład pomyśl o długotrwałym procesie, który początkowo dotyka pamięci w celu jednorazowej pracy, ale potem nie zwalnia pamięci i działa w tle. Jądro będzie musiało używać do tego pamięci RAM, dopóki proces się nie zakończy. Bez wymiany jądro nie może znaleźć strony, która chciałaby aktywnie korzystać z pamięci RAM. Zastanów się także, ilu programistów jest leniwych i nie zwalnia wprost pamięci po użyciu.
Dotyczy to tylko jednego procesu i prawdopodobnie jest to rozsądne założenie, że proces nie powinien żądać więcej pamięci niż system fizycznie! Prawdopodobnie więc warto powstrzymać samotny szalony proces przed wyzwalaniem thrashingu, będąc jednocześnie hojnie nastawionym.
Fajny pomysł, ale wtedy te programy wymażą pamięć, której nie używają aktywnie. Dopuszczalne może być, jeśli program zażąda tylko niewielkiej ilości pamięci.
Wydanie systemd 232 właśnie dodało kilka opcji, które to umożliwiają: Myślę, że można użyć „MemorySwapMax = 0”, aby zapobiec wymianie pamięci przez jednostkę (usługę), taką jak ssh.
Niemniej jednak lepszym rozwiązaniem byłoby ustalenie priorytetu dostępu do pamięci.
Długie wyjaśnienie
Jądro Linuksa jest lepiej dostrojone do obciążeń serwera, więc reakcja GUI była niestety drugorzędną kwestią ... Ustawienia zarządzania pamięcią jądra w wersji Ubuntu 16.04 LTS na pulpicie nie różniły się od innych wersji serwera. Jest nawet zgodny z domyślnymi w RHEL / CentOS 7.2 zwykle używanym jako serwer.
OOM, ulimit i kompromis uczciwość dla reaktywności
Wymiana thrash (gdy działający zestaw pamięci, tj. Strony odczytywane i zapisywane w danym krótkim przedziale czasowym przekraczają fizyczną pamięć RAM) zawsze blokuje pamięć I / O pamięci - żadne działanie jądra nie może uratować systemu przed zabiciem procesu lub dwa...
Mam nadzieję, że poprawki Linux OOM pojawiające się w nowszych jądrach rozpoznają, że ten zestaw roboczy przekracza sytuację w pamięci fizycznej i zabija proces. Kiedy tak się nie dzieje, pojawia się problem z drżeniem. Problem polega na tym, że przy dużej partycji wymiany może wyglądać, jakby system nadal miał nadmiar, podczas gdy jądro wesoło przesuwa się i obsługuje żądania pamięci, ale zestaw roboczy może przelać się na wymianę, skutecznie próbując traktować pamięć tak, jakby to RAM.
Na serwerach akceptuje karę za wydajność polegającą na przerzucaniu za określone, wolne, nie tracące danych, kompromisy. Na komputerach kompromis jest inny i użytkownicy wolą trochę utraty danych (poświęcenie procesu), aby zachować szybkość reakcji.
To była fajna komiczna analogia do OOM: oom_pardon, czyli nie zabijaj mojego xlocka
Nawiasem mówiąc,
OOMScoreAdjust
jest kolejną systemową opcją, która pomaga ważyć i unikać procesów zabijania OOM, uważanych za ważniejsze.buforowany zapis zwrotny
Myślę, że „ Spraw, aby zapisywanie w tle nie było do bani ” pomoże uniknąć pewnych problemów, w których proces zapełniający pamięć RAM powoduje kolejną zamianę (zapis na dysk), a masowe zapisywanie na dysk zatrzymuje wszystko, co chce IO. Sam problem nie jest przyczyną przeładowania, ale przyczynia się do ogólnego pogorszenia reakcji.
ogranicza ograniczenia
Jednym z problemów z ulimits jest to, że rozliczanie limitu dotyczy przestrzeni adresowej pamięci wirtualnej (co oznacza łączenie zarówno przestrzeni fizycznej, jak i przestrzeni wymiany). Zgodnie z
man limits.conf
:Tak więc ustawienie ulimit tak, aby dotyczyło tylko fizycznego użycia pamięci RAM, nie wygląda już na użyteczne. Stąd
wydaje się być jedynym szanowanym dostrajaniem.
Niestety, jak szczegółowo opisano na przykładzie WebKit / Gnome, niektóre aplikacje nie mogą działać, jeśli przydzielanie wirtualnej przestrzeni adresowej jest ograniczone.
cgroups powinien pomóc w przyszłości?
Obecnie wydaje się to kłopotliwe, ale możliwe jest włączenie niektórych flag cgroup jądra
cgroup_enable=memory swapaccount=1
(np. W grub config), a następnie spróbuj użyć kontrolera pamięci cgroup, aby ograniczyć użycie pamięci.Grupy c mają bardziej zaawansowane funkcje limitu pamięci niż opcje „ulimit”. Notatki CGroup v2 wskazują na próby poprawy działania ulimits.
Opcje CGroup można ustawić za pomocą opcji systemowej kontroli zasobów . Na przykład:
Inne przydatne opcje mogą być
Mają one pewne wady:
W CGroup v2 sugerują, że
memory.high
powinna to być dobra opcja do ograniczenia przepustowości i zarządzania wykorzystaniem pamięci przez grupę procesów. Jednak ten cytat sugeruje, że monitorowanie sytuacji presji pamięci wymagało więcej pracy (od 2015 r.).Biorąc pod uwagę, że narzędzia przestrzeni systemowej i cgroup są złożone, nie znalazłem prostego sposobu, aby ustawić coś odpowiedniego i wykorzystać to dalej. Dokumentacja cgroup i systemd dla Ubuntu nie jest świetna. Przyszłe prace powinny dotyczyć dystrybucji z wydaniami stacjonarnymi, aby wykorzystać grupy i systemd, aby pod wysokim ciśnieniem pamięci ssh i komponenty X-Server / menedżera okien otrzymały wyższy priorytet dostępu do procesora, fizycznej pamięci RAM i IO pamięci, aby uniknąć konkurowania z procesami zajęta zamiana. Funkcje jądra procesora i priorytetowe we / wy istnieją już od jakiegoś czasu. Wydaje się, że jest to priorytetowy dostęp do brakującej fizycznej pamięci RAM.
Jednak nawet priorytety procesora i IO nie są odpowiednio ustawione !? Kiedy sprawdziłem systemowe limity grupy, zastosowane udziały procesora itp., O ile mogłem stwierdzić, Ubuntu nie ustawił żadnych uprzednio zdefiniowanych priorytetów. Np. Prowadziłem:
Porównałem to z tym samym wyjściem dla ssh, samba, gdm i nginx. Ważne rzeczy, takie jak GUI i zdalna konsola administracyjna, muszą walczyć na równi ze wszystkimi innymi procesami, gdy dochodzi do thrashowania.
Przykładowe limity pamięci, które mam w systemie 16 GB RAM
Chciałem włączyć hibernację, więc potrzebowałem dużej partycji wymiany. Stąd próba złagodzenia za pomocą ulimitów itp.
ulimit
I umieścić
* hard as 16777216
w/etc/security/limits.d/mem.conf
taki sposób, że żaden proces nie będą mogły żądać więcej pamięci, niż jest to fizycznie możliwe. Nie będę zapobiegać wyrzucaniu wszystkich razem, ale bez tego tylko jeden proces z chciwym użyciem pamięci lub wyciek pamięci może spowodować wyrzucenie. Np. Widziałem,gnome-contacts
jak zajmowałem ponad 8 GB pamięci podczas robienia przyziemnych czynności, takich jak aktualizowanie globalnej listy adresów z serwera wymiany ...Jak widać
ulimit -S -v
, w wielu dystrybucjach ten twardy i miękki limit jest ustawiony jako „nieograniczony”, teoretycznie proces może skończyć się żądaniem dużej ilości pamięci, ale tylko aktywnie korzystaniem z podzbioru, i działa z radością, myśląc, że otrzymał 24 GB pamięci RAM system ma tylko 16 GB. Powyższy twardy limit spowoduje, że procesy, które mogły działać poprawnie, zostaną przerwane, gdy jądro odmówi ich chciwych spekulacyjnych żądań pamięci.Jednak łapie również szalone rzeczy, takie jak kontakty gnomów i zamiast stracić czas reakcji pulpitu, pojawia się błąd „niewystarczającej ilości wolnej pamięci”:
Komplikacje ustawiające ulimit dla przestrzeni adresowej (pamięć wirtualna)
Niestety niektórzy programiści lubią udawać, że pamięć wirtualna jest nieskończonym zasobem, a ustawienie limitu pamięci wirtualnej może uszkodzić niektóre aplikacje. Np. WebKit (od którego zależą niektóre aplikacje gnome) dodał funkcję
gigacage
bezpieczeństwa, która próbuje przydzielić szaloną ilość pamięci wirtualnej i pojawiają sięFATAL: Could not allocate gigacage memory
błędy z podstępną wskazówkąMake sure you have not set a virtual memory limit
. Obejście,GIGACAGE_ENABLED=no
rezygnuje z korzyści związanych z bezpieczeństwem, ale podobnie, niedozwolone ograniczenie alokacji pamięci wirtualnej, również rezygnuje z funkcji bezpieczeństwa (np. kontrola zasobów, która może zapobiec odmowie usługi). Jak na ironię, między twórcami gigacage i gnome wydaje się, że zapominają, że samo ograniczenie pamięci to kontrola bezpieczeństwa. I niestety zauważyłem, że aplikacje gnome oparte na gigacage nie zawracają sobie głowy jawnym żądaniem wyższego limitu, więc nawet miękki limit psuje rzeczy w tym przypadku.Szczerze mówiąc, jeśli jądro lepiej sobie poradzi z możliwością odmowy przydzielenia pamięci na podstawie użycia pamięci rezydentnej zamiast pamięci wirtualnej, udawanie, że pamięć wirtualna jest nieograniczona, byłoby mniej niebezpieczne.
przesada
Jeśli wolisz, aby aplikacje nie miały dostępu do pamięci i chcesz przestać przesadzać, użyj poniższych poleceń, aby sprawdzić, jak zachowuje się twój system pod wysokim ciśnieniem pamięci.
W moim przypadku domyślnym współczynnikiem zatwierdzenia było:
Ale staje się to w pełni skuteczne tylko podczas zmiany zasad, aby wyłączyć nadpisywanie i zastosować współczynnik
Współczynnik sugerował, że ogólnie można przydzielić tylko 24 GB pamięci (16 GB RAM * 0,5 + 16 GB SWAP). Prawdopodobnie nigdy nie widziałbym, aby OOM się pojawił, i faktycznie mniej prawdopodobne jest, aby procesy stale uzyskiwały dostęp do pamięci podczas wymiany. Ale prawdopodobnie poświęcę też ogólną wydajność systemu.
Spowoduje to awarię wielu aplikacji, zważywszy, że deweloperzy często nie wdzięcznie obsługują system operacyjny, odrzucając żądanie alokacji pamięci. Zapobiega sporadycznemu ryzyku wyciągnięcia blokady z powodu przeładowania (utrata całej pracy po twardym resecie) do częstszego ryzyka awarii różnych aplikacji. W moich testach niewiele to pomogło, ponieważ sam komputer zawiesił się, gdy system był pod presją pamięci i nie mógł przydzielić pamięci. Jednak przynajmniej konsole i SSH nadal działały.
Jak działa pamięć Overcommit VM, ma więcej informacji.
Zdecydowałem się na przywrócenie domyślnych ustawień
sudo sysctl -w vm.overcommit_memory=0
, biorąc pod uwagę cały stos graficzny pulpitu i aplikacje w nim występujące.źródło
but the kernel won't be able to use an overcommit strategy for allocating memory and this will likely hurt performance. Even a smaller swap partition allows this.
Czy jest na to jakiś dowód? Wierzę, że jądro zbyt dobrze się przepełnia bez skonfigurowanej wymiany