Wszyscy tego doświadczyliśmy - jakiś program jest proszony o zrobienie czegoś, co wymaga ogromnej ilości pamięci. Sumiennie próbuje przydzielić całą tę pamięć, a system natychmiast zaczyna bić, zamieniać bez końca i staje się powolny lub nie reaguje.
Ostatnio doświadczyłem tego na moim laptopie z Ubuntu, ponieważ skrypt Matlab próbuje przydzielić absurdalnie ogromną matrycę. Po około 5 + minutach thrashingu byłem w stanie Ctrl-F1 na konsoli i zabić Matlaba. Wolałbym mieć jakiś skrót klawiszowy, który dałby mi natychmiast kontrolę nad systemem i pozwolił mi zabić przestępcę; a może po prostu w milczeniu odmawiają przydzielenia tak dużego bufora.
Jaki jest najszybszy sposób na odzyskanie kontroli nad systemem Linux, który przestał reagować lub był bardzo powolny z powodu nadmiernej wymiany?
Czy istnieje skuteczny sposób, aby przede wszystkim zapobiec takiej zamianie, na przykład poprzez ograniczenie ilości pamięci, którą proces może przydzielić?
Już odpowiedziałem powyżej za pomocą Alt-SysRq-F
Odpowiadam na drugą część. Tak,
ulimit
nadal działa wystarczająco dobrze, aby ograniczyć pojedynczy proces. Możesz:Ponadto, jak krótko wspomniano:
Rzeczywiście, cgroups oferują bardziej zaawansowaną kontrolę, ale obecnie moim zdaniem są bardziej skomplikowane w konfiguracji.
Old school ulimit
Raz wolny
Oto prosty przykład:
To:
r2(){ r2 $@$@;};r2 r2
, która wykładniczo przeżuwa procesor i pamięć RAM, nieskończenie podwajając się podczas żądania pamięci stosu.Jak widać, został zatrzymany podczas próby żądania więcej niż 1 GB.
Uwaga,
-v
działa na zasadzie alokacji pamięci wirtualnej (ogółem, tj. Fizyczna + zamiana).Stała ochrona
Aby ograniczyć alokacji pamięci wirtualnej
as
jest równoważny-v
dlalimits.conf
.Wykonuję następujące czynności, aby zabezpieczyć się przed jakimkolwiek niewłaściwym procesem:
address space limit = <physical memory> - 256MB
.Jedna wkładka:
Aby sprawdzić poprawność, wynik jest następujący (np. W systemie 16 GB):
Uwagi:
rss
opcji w limit.conf. Nie jest szanowany przez nowsze jądra.Nowsze grupy C
Oferuje większą kontrolę, ale obecnie jest bardziej skomplikowany w użyciu:
memory.max_usage_in_bytes
może osobno rozliczać i ograniczać pamięć fizyczną.ulimit -m
i / lubrss
inlimits.conf
miał oferować podobną funkcjonalność, ale to nie działa od jądra Linuksa 2.4.30!cgroup_enable=memory swapaccount=1
.cgm
teraz wydaje się być oficjalnie obsługiwanym narzędziem przestrzeni użytkownika.Np. Aby sprawdzić bieżące ustawienia:
Np. Aby ograniczyć pamięć pojedynczego procesu:
Aby zobaczyć, jak działa, przeżuwa pamięć RAM jako proces w tle, a następnie ginie:
Zwróć uwagę na wykładniczy (potęga 2) wzrost liczby żądań pamięci.
W przyszłości zobaczmy, jak „dystrybucja / dostawcy” wstępnie konfigurują priorytety i limity grupy (za pomocą jednostek systemowych) dla ważnych rzeczy, takich jak SSH i stos graficzny, tak aby nigdy nie brakowało im pamięci.
źródło
Możesz nacisnąć Ctrl-, zaby zawiesić program. Następnie możesz to zrobić
kill %1
(niezależnie od tego, jaki jest numer zadania lub możesz użyć PID).Możesz użyć tego
ulimit
polecenia, aby spróbować ograniczyć ilość pamięci dostępnej dla procesu.źródło
kill -STOP <pid>
który zrobi to samo co Ctrl-Z.Możesz użyć CGroups, aby ograniczyć wykorzystanie zasobów i zapobiec takim problemom: https://en.wikipedia.org/wiki/Cgroups
źródło
Zawsze jest klasyczne
xkill
polecenie (z xorg-x11-apps-7.4-14.fc14.src.rpm w moim systemie). Wydaje mi się, że stworzenie klona, który wysyła SIGSTOP, zamiast zabijać okno docelowe, nie powinno być zbyt trudne.źródło