Jak z wdziękiem rozwiązać ten problem z pamięcią?


10

Mam standardowy laptop z systemem Linux (testy Debiana) z partycją wymiany.

Robię z nim wiele eksperymentów. Niektóre z nich są naprawdę wymagające pamięci, a sposób, w jaki Linux domyślnie się zachowuje, jest dla mnie problemem ... Dajmy głupi przykład:

  1. Usiądź przed laptopem
  2. Otwórz terminal
  3. Wpisz pythonwięca = [0]*100000000

Teraz są duże szanse, że nie będziesz mieć wystarczającej ilości pamięci RAM, aby obsłużyć tę dużą listę. Linux zapełni pamięć RAM, następnie zamieni się, a kilka minut później zabójca OOM zostanie uruchomiony i zabije (prawie) losowe usługi i miejmy nadzieję, że jeśli naciśniesz Ctrl + C we właściwym czasie pythoni jeśli terminal nadal był skupiony, komputer ponownie zareaguje.

Chciałbym egzekwować pewne limity pamięci, aby uniknąć niechcianej zamiany i odmówić procesowi prawa do przydzielenia większej ilości pamięci niż mam (w pamięci RAM). Jeśli zapotrzebowanie na pamięć jest poniżej określonego limitu lub jest wymagane przez roota, po prostu zabij proces najbardziej wymagający pamięci dowolnego użytkownika z wyjątkiem roota.

ulimit -Sv [mem] Słyszę z tyłu!

Ho Ho! „Użyj cgroupsprzez cgexec!” ktoś mówi w pierwszym rzędzie!

Tak, masz rację: są to naprawdę bardzo dobre rozwiązania. Ale:

  • Nie dotyczą całego systemu
  • Limity są ustalane dla poszczególnych procesów
  • Limity są stałe, bez względu na rzeczywistą ilość wolnej pamięci RAM (AFAIK)
  • Tu i tam mówią, że to nie jest naprawdę dobre rozwiązanie do egzekwowania twardych limitów.

Chciałbym, aby jądro powiedział: „Należysz do użytkownika foo (nie root), używasz dużo pamięci, a zabraknie nam pamięci. Przepraszam stary ... umrzyj teraz!”

Lub: „Co do diabła robisz? Potrzebujesz x MB, a jest tylko y MB MB. Tak, SWAP jest pusty, ale nie zamierzasz używać SWAP do wykonywania swojej brudnej roboty, prawda? Nie, ja powiedział nie! Brak pamięci dla ciebie! Jeśli nalegasz, umrzesz!


2
W tym artykule opisano już algorytm, który pomaga zabójcy OOM wybrać prawidłowy proces. Zmiana /proc/sys/vm/overcommit_memorywpływa na zachowanie jądra przy małej ilości pamięci.
jofel

1
Tak, ale overcommit_memoryplik specjalny używa pamięci RAM + SWAP jako użytecznej pamięci. Nadal zamierzam zamienić :)

1
Musisz także wyjaśnić, że nie jest to duplikat tego: unix.stackexchange.com/questions/34334/... co jest sprzeczne z grupami WRT i poszczególnymi użytkownikami. PS. Jeśli nie chcesz zamieniać, wyłącz zamianę .
goldilocks,

1
Chcę zamienić! Chcę hibernacji, chcę, aby nieużywane bajty były przechowywane! Ale nie chcę, aby używane bajty były tam przechowywane. Jeśli chodzi o link, ulimitsto zły pomysł, jak pokazano prawie wszędzie, ponieważ jest to ograniczenie na proces ... Rozumiem, wiesz :) O cgroups, to zdecydowanie lepsze, ale brakuje czegoś bardziej ogólnego: mówię o moim laptopie, ale także posiadać serwer „obliczeniowy”, którym dzielimy się trzema. Jeśli egzekwuję takie limity na użytkownika, będę ograniczany przez najgorszy scenariusz, prawda?

1
cgroups mają zastosowanie do każdego procesu, który wybierzesz - umieść wszystkie procesy użytkownika w osobnej grupie i powinno to robić, co chcesz.
peterph

Odpowiedzi:


4

Ktoś zasugerował ci w twoim głosie cgroups. Staraj się szukać tego kierunku, ponieważ może on zapewnić:

  • zastosowane do grupy zadań, które wybierzesz (a więc nie obejmuje całego systemu, ale nie dotyczy jednego procesu)
  • limity są ustawione dla grupy
  • limity są statyczne
  • mogą egzekwować twardy limit pamięci i / lub pamięci + zamiana

Coś takiego może przybliżyć cię do twoich celów :

group limited {
  memory {
    memory.limit_in_bytes = 50M;
    memory.memsw.limit_in_bytes = 50M;
  }
}

Mówi to, że zadania w tej grupie mogą używać maksymalnie 50 MB pamięci i 50 MB pamięci + zamiana, więc gdy pamięć jest pełna, nie zamienia się, ale jeśli pamięć nie jest pełna i niektóre dane mogą zostać zmapowane w zamiana, to może być dozwolone.

Oto fragment dokumentacji pamięci grupy cgroup :

Używając limitu memsw, możesz uniknąć OOM systemu, który może być spowodowany brakiem wymiany.


Nadal nie do końca to, czego się spodziewałem. Ale różnica między tym, czego oczekuję, a rzeczywistością jest często dość duża :) W tym przypadku chciałem mieć pewność, że nie umknęło mi nic takiego jak overcommit_memoryzmienna jądra. Dziękuję wam wszystkim.

0

Często napotykam ten sam problem. Mój ogólny przepływ pracy obejmuje ciężkie obliczenia w MATLAB. Czasami nieumyślnie spróbuję przydzielić nową zmienną, która przekracza ilość dostępnej pamięci. System zawiesza się i zazwyczaj muszę ponownie uruchomić komputer, aby wrócić do pracy. : P

W moim przypadku i brzmi to tak samo jak w twoim, nie byłem tak bardzo zainteresowany ograniczeniem ilości pamięci, jaką MATLAB używa do statycznej ilości - byłem zainteresowany brakiem zamrożonej maszyny i byłem gotów poświęcić mój proces MATLAB w celu zachowania reaktywności systemu.

Zainspirowany odpowiedzią na ten post napisałem następujący skrypt (nazwałem go watch_memory.sh):

#!/bin/bash

MONITOR=$(free | grep 'buffers/cache:')
MEM_USED=$(echo $MONITOR | awk '{ print $3 }')
MEM_FREE=$(echo $MONITOR | awk '{ print $4 }')

MEM_PERC=$(( 100*MEM_USED / (MEM_FREE+MEM_USED) ))

while :; do
    if [ "$MEM_PERC" -gt "95" ]
    then
        kill $1
        echo "$1 killed for using too much memory."
        exit
    fi
    sleep 1

    MONITOR=$(free | grep 'buffers/cache:')
    MEM_USED=$(echo $MONITOR | awk '{ print $3 }')
    MEM_FREE=$(echo $MONITOR | awk '{ print $4 }')
    MEM_PERC=$(( 100*MEM_USED / (MEM_FREE+MEM_USED) ))
done

Ten skrypt sprawdza co sekundę procentową ilość wolnej pamięci. Kiedy system się wyczerpie, twój kozioł ofiarny (przekazany jako argument do skryptu) zostaje zabity.

Bez zmiany priorytetu (bezwzględności) skryptu zabicie kozła ofiarnego zajęło około 10-20 sekund, ale nadal działało. Uruchomienie skryptu z priorytetem ujemnym spowodowało natychmiastowe zabicie po naruszeniu (11916 w tym przykładzie to pid, który chcę zabić, jeśli zabraknie mi pamięci):

sudo nice -n -5 bash watch_memory.sh 11916
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.