Ubuntu szybko zaczyna brakować pamięci RAM, a mój komputer zaczyna się zawieszać. Jakie polecenie to rozwiąże?

73

Zdarza mi się to dość często, kiedy kompiluję oprogramowanie w tle i nagle wszystko zaczyna zwalniać i ostatecznie zamarzać [jeśli nic nie robię], ponieważ skończyły mi się zarówno pamięć RAM, jak i przestrzeń wymiany.

To pytanie zakłada, że ​​mam wystarczająco dużo czasu i zasobów, aby otworzyć Terminal Gnome, przeszukać moją historię i wykonać jedno sudopolecenie.

Jakie polecenie może mnie uratować przed koniecznością ponownego uruchomienia komputera lub jakiegokolwiek ponownego uruchomienia?

Akiva
źródło
Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
Thomas Ward
1
Jeśli zabraknie Ci przestrzeni wymiany, myślę, że masz jej za mało. Mam 20G przestrzeni wymiany na tym komputerze. Chodzi o to, aby dać ci wystarczająco dużo czasu z użytecznym systemem, aby zabić wszystko, co pochłania twoją pamięć. To nie jest coś, w którym bierzesz tylko to, czego będziesz używać, ale to, co masz nadzieję, że nigdy nie użyjesz.
JoL
1
Czy jesteś pewien, że zarówno RAM, jak i swap są zapełniane? Gdyby tak było, moduł obsługi OOM zabiłby kompilator i zwolniłby pamięć (a także spieprzyłby proces kompilacji). W przeciwnym razie myślę, że się zapełnia, a może twój system działa wolno, ponieważ twoja wymiana jest na dysku systemowym.
sudo
3
Spróbuj zmniejszyć liczbę równoległych kompilacji, jeśli nie masz wystarczającej ilości pamięci RAM do jej obsługi. Jeśli twoja kompilacja zacznie się zmieniać, będziesz znacznie wolniejszy. Za pomocą makespróbuj -j4na przykład dla 4 równoległych wersji na raz.
Shahbaz
1
„Alexa zamów mi 8 koncertów

Odpowiedzi:

84

Z mojego doświadczenia wynika, że ​​Firefox i Chrome zużywają więcej pamięci RAM niż moje pierwsze 7 komputerów łącznie. Prawdopodobnie więcej niż to, ale uciekam od mojego punktu. Pierwszą rzeczą, którą powinieneś zrobić, to zamknąć przeglądarkę . Komenda?

killall -9 firefox google-chrome google-chrome-stable chromium-browser

Połączyłem tam najpopularniejsze przeglądarki w jedno polecenie, ale oczywiście jeśli używasz czegoś innego (lub wiesz, że nie używasz jednego z nich), po prostu zmodyfikuj to polecenie. To killall -9 ...jest ważny kawałek. Ludziom nie podoba się SIGKILL(sygnał numer 9), ale przeglądarki są wyjątkowo odporne. Co więcej, powolne zakończenie przez SIGTERMoznacza, że ​​przeglądarka robi mnóstwo śmieci po czyszczeniu - co wymaga dużej ilości dodatkowej pamięci RAM - i na to nie możesz sobie pozwolić w tej sytuacji.

Jeśli nie możesz dostać się do już działającego terminala lub dialogu Alt+ F2, rozważ zmianę na TTY. Control+ Alt+ F2przeniesie Cię do TTY2, który powinien pozwolić ci się zalogować (choć może być powolny), a nawet pozwolić ci użyć czegoś takiego jak htopdebugowanie problemu. Nie sądzę, że kiedykolwiek zabrakło mi pamięci RAM do tego stopnia, że ​​nie mogłem wstać htop.

Długoterminowe rozwiązanie polega albo na zakupie większej ilości pamięci RAM, wypożyczeniu jej za pośrednictwem zdalnego komputera lub na niewykonaniu tego, co obecnie robisz. Pozostawię ci skomplikowane argumenty ekonomiczne, ale ogólnie rzecz biorąc, RAM jest tani w zakupie, ale jeśli potrzebujesz tylko ilości seryjnej, serwer VPS naliczany za minutę lub godzinę jest dobrym wyborem.

Oli
źródło
Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
Thomas Ward
Mam lazygitod czasu do czasu kilka poleceń powiązanych z własnym poleceniem, może coś takiego można zastosować tutaj? Cały killall ...skrypt można sprowadzić do prostego emptyramlub czegoś takiego
Francisco Presencia
Nie musisz uruchamiać pełnego polecenia, jeśli wiesz, która przeglądarka jest uruchomiona, i zakładam, że większość osób, które potrafią zidentyfikować brak pamięci RAM, robi. W związku z tym trudniej byłoby mi zapamiętać, że napisałem emptyramscenariusz, niż po prostu wbić go killall -9 firefox.
Oli
2
Kupowanie pamięci RAM ... dlaczego nie po prostu pobrać więcej pamięci RAM?
Stephan Bijzitter
1
Cóż, możesz żartować, ale jeśli musisz zrobić coś na krótki czas, co wymaga znacznie więcej pamięci RAM i procesora, to wynajęcie VPS na minutę jest dość ekonomiczne dla pojedynczych zdjęć.
Oli
66

W systemie z włączonym klawiszem żądania magicznego systemu naciśnięcie Alt + System Request+ f(jeśli nie jest zaznaczone na klawiaturze, System Requestczęsto znajduje się na Print Screenklawiszu) spowoduje ręczne wywołanie zabójcy pamięci poza jądrem (oomkiller), który próbuje wybrać najgorszy proces obrażania dla użycie pamięci i zabij to. Możesz to zrobić, jeśli masz mniej czasu, niż opisałeś, a system właśnie zaczyna (lub może już zaczął) thrashowanie - w takim przypadku prawdopodobnie nie obchodzi Cię dokładnie, co zostanie zabite, tylko to, że skończysz z użytecznym systemem. Czasami może to doprowadzić do zabicia X, ale w dzisiejszych czasach dużo lepiej jest wybrać zły proces niż kiedyś.

Muzer
źródło
5
@ T.Sar, jeśli od razu zaczynasz szaleć, albo już przegrywasz, albo masz szansę zabić pożeracza pamięci. Nic nie zyskasz, jeśli po prostu powstrzymasz się od działania.
Ruslan
4
@Muzer zadziała to tylko wtedy, gdy ustawiłeś kernel.sysrqna 1lub liczbę zawierającą właściwy bit w twoim /etc/sysctl.d/10-magic-sysrq.conf.
Ruslan
9
@ T.Sar Nie stracisz postępów, jeśli używasz zdrowego systemu kompilacji. Zachowasz wszystkie pliki obiektowe, ale ten, który faktycznie kompilowałeś, a następnie wrócisz do miejsca, w którym przerwałeś.
Muzer
3
@ T.Sar To, że kompilujesz nie jest normalne, nie oznacza, że ​​system kompilacji nie jest normalny. Buduj systemy od niepamiętnych czasów przechowując pliki obiektów do ponownego wykorzystania w kolejnych kompilacjach. Z drugiej strony z pewnością mogę wymienić wiele projektów oprogramowania z mniejszym rozsądkiem niż Linux (który jest ogólnie całkiem dobrze zaprojektowany). Na przykład kompilując coś takiego jak Firefox lub OpenOffice z 8 równoległymi wątkami kompilacji, mogę łatwo zauważyć, że bierze to w kolejności gigabajty pamięci RAM. Istnieje również wiele monolitycznych systemów korporacyjnych, które zależą od setek bibliotek.
Muzer
7
@ T.Sar Linux nie jest tak naprawdę skomplikowany z POV kompilatora. W rzeczywistości nie ma prawie żadnych programów typu C. Co z C ++? Czy próbowałeś kiedyś zbudować program przy użyciu Eigen lub Boost? Zdziwiłbyś się, ile pamięci kompilator czasami zjada z takimi programami - i same nie muszą być skomplikowane.
Ruslan
20

W przeciwieństwie do innych odpowiedzi, sugeruję wyłączenie wymiany podczas wykonywania tej czynności. Podczas gdy zamiana utrzymuje system w przewidywalny sposób i jest często używana do zwiększenia przepustowości aplikacji uzyskujących dostęp do dysku (poprzez eksmisję nieużywanych stron, aby zapewnić miejsce na pamięć podręczną dysku), w tym przypadku wygląda na to, że system jest spowolniony do poziomów bezużytecznych, ponieważ zbyt aktywnie wykorzystywana pamięć jest zmuszana do eksmisji.

Zalecałbym całkowite wyłączenie wymiany podczas wykonywania tego zadania, aby zabójca braku pamięci zadziałał, gdy tylko pamięć RAM się zapełni.

Alternatywne rozwiązania:

  • Zwiększ szybkość odczytu wymiany, umieszczając partycję wymiany w RAID1
    • Lub RAID0, jeśli czujesz się ryzykowny, ale zmniejszy to liczbę uruchomionych programów, jeśli któryś z dysków ulegnie awarii.
  • Zmniejsz liczbę równoczesnych zadań budowania („więcej rdzeni = większa prędkość”, wszyscy mówimy, zapominając, że zajmuje to liniowe żniwo w pamięci RAM)
  • Może to działać w obie strony, ale spróbuj włączyć zswapw jądrze. Spowoduje to kompresowanie stron przed wysłaniem ich do zamiany, co może zapewnić wystarczającą ilość miejsca na poruszanie się, aby przyspieszyć maszynę. Z drugiej strony może to po prostu stanowić przeszkodę przy dodatkowej kompresji / dekompresji.
  • Wyłącz optymalizacje lub użyj innego kompilatora. Optymalizacja kodu może czasem zająć kilka gigabajtów pamięci. Jeśli masz włączone LTO, będziesz również używał dużej ilości pamięci RAM na etapie łączenia. Jeśli wszystko inne zawiedzie, możesz spróbować skompilować projekt przy użyciu lżejszego kompilatora (np. tcc) Kosztem niewielkiego spadku wydajności w czasie wykonywania skompilowanego produktu. (Jest to zazwyczaj dopuszczalne, jeśli robisz to w celach programistycznych / debugowania).
Score_Under
źródło
6
Jeśli wyłączyłeś swap, to zachowanie Linuksa, gdy zabraknie pamięci. Jeśli Linux nie wywoła zabójcy braku pamięci, ale zamiast tego zawiesza się, może to oznaczać, że z instalacją występują głębsze problemy. Oczywiście, jeśli swap jest włączony, zachowanie jest nieco inne.
Score_Under
10
@Akiva Czy próbowałeś kiedyś bez zamiany? Ta odpowiedź jest natychmiastowa. Chciałbym dodać, że uruchomienie sudo swapoff -amoże cię uratować, gdy jesteś już w powiązaniu: natychmiast przerwie to dodatkowe wykorzystanie przestrzeni wymiany, tj. Zabójca OOM powinien zostać wywołany w następnej chwili i przywrócić maszynę do stanu gotowości. sudo swapoff -ajest również doskonałym środkiem ostrożności podczas debugowania wycieków pamięci lub kompilacji, powiedzmy, firefox. Zwykle zamiana jest nieco przydatna (np. Do hibernacji lub zamiany naprawdę niepotrzebnych rzeczy), ale kiedy faktycznie używasz pamięci, zawieszanie się jest gorsze.
Jonas Schäfer
2
@Score_Under: Oddzielne partycje wymiany na każdym dysku powinny być znacznie wydajniejsze niż wymiana na urządzeniu md raid0. Zapominam, gdzie to czytam. Linux RAID wiki zaleca oddzielne partycje zamiast raid0, ale nie mówi nic mocnego o tym, dlaczego jest lepszy . W każdym razie tak, RAID1 lub RAID10n2 ma sens dla zamiany, szczególnie jeśli przeważnie chcesz po prostu zamienić niektóre brudne, ale bardzo zimne strony, aby zostawić więcej pamięci RAM dla pamięci podręcznej. tzn. wydajność wymiany nie jest wielkim problemem.
Peter Cordes
2
Chodzi mi o to, że zgodnie z twoją radą nie można w ogóle uruchomić tych programów, ponieważ wymagają one zamiany. Kompilacja, która nie powiedzie się przez 100% czasu, jest gorsza niż kompilacja, która ma 50% szans na zablokowanie systemu, prawda?
Dmitrij Grigoryev
2
Bez wymiany na wielu komputerach nie można skompilować dużych fragmentów kodu. Dlaczego miałbyś zakładać, że jest to kompilacja, którą chce poświęcić?
David Schwartz
14

Możesz użyć następującego polecenia (w razie potrzeby wielokrotnie), aby zabić proces przy użyciu największej ilości pamięci RAM w systemie:

ps -eo pid --no-headers --sort=-%mem | head -1 | xargs kill -9

Z:

  • ps -eo pid --no-headers --sort=-%mem: wyświetla identyfikatory wszystkich uruchomionych procesów posortowane według zużycia pamięci
  • head -1: zachowaj tylko pierwszą linię (proces z największą ilością pamięci)
  • xargs kill -9: zabić proces

Edytuj po dokładnym komentarzu Dmitry'ego:

Jest to szybkie i brudne rozwiązanie, które należy wykonać, gdy nie są uruchomione wrażliwe zadania (zadania, których nie chcesz kill -9).

Gohu
źródło
5
Jest to o wiele gorsze niż pozwolenie zabójcy OOM poradzić sobie z sytuacją. Zabójca OOM jest znacznie mądrzejszy. Czy naprawdę uruchamiasz takie polecenia na komputerze z trwającymi kompilacjami?
Dmitrij Grigoryev
@DmitryGrigoryev to takie mądre, że czasami zabijam Xorga na moim pulpicie. W nowoczesnych jądrach wydaje się, że OOMK nabrał trochę zdrowia psychicznego, ale po tym wszystkim tak naprawdę nie ufałbym.
Ruslan
11

Przed uruchomieniem poleceń zużywających zasoby można również użyć wywołania systemowego setrlimit (2) , prawdopodobnie z ulimitwbudowaną powłoką bash (lub limitwbudowanym w Zsh), szczególnie z -vfor RLIMIT_AS. Wtedy zbyt duże zużycie wirtualnej przestrzeni adresowej (np. Z mmap (2) lub sbrk (2) używanym przez malloc (3) ) zakończy się niepowodzeniem (przy czym errno (3) jest ENOMEM).

Wtedy one (tj. Głodne procesy w twojej powłoce, po wpisaniu ulimit) zostaną zakończone przed zamrożeniem twojego systemu.

Przeczytaj także Linux Ate My RAM i rozważ wyłączenie nadmiernej ilości pamięci (uruchamiając komendę echo 0 > /proc/sys/vm/overcommit_memory jako root, zobacz proc (5) ...).

Basile Starynkevitch
źródło
11

zdarza mi się to dość często, gdy kompiluję oprogramowanie w tle

W takim przypadku coś takiego jak „killall -9 make” (lub cokolwiek, czego używasz do zarządzania kompilacją, jeśli nie make). Zapobiegnie to dalszemu kompilowaniu, ZATRZYMUJE wszystkie uruchomione z niego procesy kompilatora (mam nadzieję, że również je zatrzymają) i jako bonus nie potrzebuje sudo, zakładając, że kompilujesz jako ten sam użytkownik, którego jesteś zalogowany. w as. A ponieważ zabija rzeczywistą przyczynę problemu zamiast przeglądarki internetowej, sesji X lub jakiegoś procesu losowo, nie będzie zakłócać tego, co robiłeś w tym czasie w systemie.

fluffysheap
źródło
2
szkoda, że ​​musiałem przewinąć do tej pory, aby znaleźć tę odpowiedź. Miałem nadzieję, że ktoś zaproponuje sposób, który zawiesi postępy w tym jedzeniu pamięci RAM.
TOOGAM
OP nie jest zbliżone do odpowiedzi, której oczekuje OP, ale odpowiada na pytanie literackie: moja maszyna do gówna staje się bezużyteczna, kiedy ją buduję - przestań budować na maszynie do gówna.
9ilsdx 9rvj 0lo
9

Stwórz więcej swapów dla siebie.

Następujące doda 8G swapu:

dd if=/dev/zero of=/root/moreswap bs=1M count=8192
mkswap /root/moreswap
swapon /root/moreswap

Nadal będzie wolno (wymieniasz), ale tak naprawdę nie powinieneś kończyć. Nowoczesne wersje systemu Linux mogą zamieniać się na pliki. Jedynym obecnie zastosowaniem partycji wymiany jest hibernacja laptopa.

William Hay
źródło
1
Mam ten sposób implementowany jako skrypt, właściwie tutaj . Całkiem przydatne do dodawania wymiany w locie.
Sergiy Kolodyazhnyy
7
Niektóre zamiany są ogólnie rozsądne, ale przydzielanie dużych kwot po prostu pozwala maszynie rzucić więcej, zanim zabije OOM i wybierze ochotnika. Sędziwa stara rola kciuka o „podwajaniu barana jak zamiana” już dawno nie żyje. Osobiście nie widzę żadnej wartości w przydzielaniu więcej niż ~ 1 GB swapów ogółem.
Criggie
5
Dzięki ext4 możesz fallocate -l 8G /root/moreswapzamiast ddunikać 8 GB operacji we / wy, gdy system jest wstrząsający. Nie działa to jednak z żadnym innym systemem plików. Zdecydowanie nie XFS, gdzie swapon widzi niepisane zakresy jako dziury. ( Wydaje mi się, że dyskusja na liście mailingowej xfs się nie potoczyła). Zobacz także swapddemon, który tworzy / usuwa pliki wymiany w locie, aby zaoszczędzić miejsce na dysku. Również askubuntu.com/questions/905668/…
Peter Cordes
1
@ Criggie „Osobiście nie widzę żadnej wartości przy przydzielaniu więcej niż ~ 1 GB wymiany ogółem” - Czy próbowałeś zbudować Firefox?
Dmitrij Grigoryev
1
@Akiva Podczas ostatniego sprawdzania zalecana konfiguracja kompilacji to 16 GB pamięci RAM. Główny plik wykonywalny ( xul.dll) ma około 50 MB, więc jest około 10 razy cięższy niż jądro Linuksa.
Dmitry Grigoryev
5

Jednym ze sposobów na uzyskanie części wolnej pamięci RAM w krótkim czasie jest użycie zram , który tworzy skompresowany dysk RAM i zamienia tam. Z każdym pół przyzwoitym procesorem jest to znacznie szybsze niż zwykła zamiana, a wskaźniki kompresji są dość wysokie w przypadku wielu współczesnych pamięci RAM, takich jak przeglądarki internetowe.

Zakładając, że masz zram zainstalowany i skonfigurowany, wszystko co musisz zrobić, to uruchomić

sudo service zramswap start
Dmitrij Grigoriew
źródło
Czy to działa na wszystkich systemach plików, takich jak btrfs?
Akiva
1
@Akiva zram nigdy nie dotyka dysku, więc powiedziałbym, że tak;)
Dmitry Grigoryev
3

sudo swapoff -awyłączy swap, dzięki czemu jądro automatycznie zabije proces z najwyższym wynikiem, jeśli w systemie zabraknie pamięci. Używam tego, jeśli wiem, że będę miał coś z pamięcią RAM, którą wolałbym zabić, jeśli wymknie się spod kontroli, niż pozwolić, aby zmienił się i utknął na zawsze. Użyj, sudo swapon -aaby ponownie włączyć go później.

Później możesz rzucić okiem na ustawienia wymiany. Wygląda na to, że twoja zamiana znajduje się na tym samym dysku, co partycja root, co spowolniłoby twój system po uruchomieniu swap, więc unikaj tego, jeśli możesz. Ponadto, moim zdaniem, nowoczesne systemy często konfigurowane są ze zbyt dużą wymianą. 32GiB RAM zwykle oznacza, że ​​zamiana 32GiB jest przydzielana domyślnie, tak jakbyś naprawdę chciał umieścić 32GiB w swoim obszarze wymiany.

sudo
źródło
Och, właśnie widziałem, że ktoś gdzieś to skomentował.
sudo
3

Inną rzeczą, którą można zrobić, to zwolnić pamięć podręczną strony pamięci za pomocą tego polecenia:

echo 3 | sudo tee /proc/sys/vm/drop_caches

Z dokumentacji kernel.org (wyróżnienie dodane):

drop_caches

Zapisanie tego spowoduje, że jądro będzie upuszczać czyste pamięci podręczne, a także obiekty płytowe, takie jak dentries i i-węzły. Po upuszczeniu pamięć staje się wolna .

Aby zwolnić pamięć podręczną: echo 1> / proc / sys / vm / drop_caches Aby zwolnić obiekty płyty podlegające zwrotowi (w tym dentries i i-węzły): echo 2> / proc / sys / vm / drop_caches Aby zwolnić obiekty płyty i pagecache: echo 3> / proc / sys / vm / drop_caches

Jest to nieniszcząca operacja i nie uwolni żadnych brudnych przedmiotów. Aby zwiększyć liczbę obiektów uwolnionych przez tę operację, użytkownik może uruchomić `sync 'przed zapisaniem do / proc / sys / vm / drop_caches. Pozwoli to zminimalizować liczbę brudnych obiektów w systemie i stworzyć więcej kandydatów do usunięcia.

Sergiy Kolodyazhnyy
źródło
Interesujące ... chcesz wyjaśnić tę logikę poleceń?
Akiva
1
@Akiva w zasadzie mówi jądro Linuksa, aby zwolnić pamięć RAM. To nie pozbywa się przyczyny, która zabija proces obrażania, więc odpowiedź Oli jest rozwiązaniem problemu. Upuszczenie pamięci podręcznej zapobiegnie wyczerpaniu się pamięci w systemie, a tym samym zapobiegnie zamrożeniu, a tym samym poświęci czas na rozwiązanie problemu. Prawdopodobnie będzie to nieco szybsze niż tworzenie pliku wymiany, zwłaszcza jeśli jesteś na dysku twardym, a nie na dysku SSD
Sergiy Kolodyazhnyy
7
Pamięć podręczna jest pierwszą rzeczą, którą należy wykonać po zapełnieniu pamięci, więc nie sądzę, aby to bardzo pomogło. W rzeczywistości nie sądzę, aby to polecenie miało praktyczne zastosowanie poza debugowaniem zachowania jądra lub optymalizacją dostępu do dysku czasowego. Pokornie odradzam uruchamianie tego polecenia w każdym systemie, który wymaga większej wydajności.
Score_Under
2
@Score_Under - „Pamięć podręczna jest pierwszą rzeczą, która pojawia się po zapełnieniu pamięci” - cóż, to zależy od twojego ustawienia /proc/sys/vm/swappiness. Przy swappiness ustawionym na 0 masz rację. Przy ustawieniu domyślnym 60 jesteś blisko. Przy ustawieniu na 200 będą to jednak ostatnio używane strony działających procesów, które zostaną upuszczone jako pierwsze ... w tym konkretnym przypadku to polecenie może być przydatne. Jednak ustawienie swapiness na 0 (lub jakąś niską wartość, może 20 lub 30) byłoby lepszym podejściem ogólnym.
Jules
3
@Score_Under To polecenie było przydatne na starych jądrach z kswapdbłędem (niektórzy nawet stworzyli z nim cronjobs). Ale masz rację, wątpię, że to pomoże w tym pytaniu.
Dmitrij Grigoryev
1

Powiedziałeś „kompilowanie w tle”. Co robisz na pierwszym planie? Jeśli programujesz w środowisku Eclipse lub innym zasobnym środowisku IDE, sprawdź, czy wszystko jest poprawnie zakończone w konsoli.

Środowiska programistyczne często pozwalają na uruchamianie wielu procesów w fazie rozwoju, mogą one również zawieszać się, gdy nie będziesz już nimi zainteresowany (w debuggerze lub po prostu nieprawidłowo ukończony). Jeśli deweloper nie zwraca uwagi, w ciągu dnia mogą gromadzić się dziesiątki zapomnianych procesów, wykorzystując jednocześnie wiele gigabajtów.

Sprawdź, czy wszystko, co powinno zostać zakończone w IDE, zostało zakończone.

h22
źródło