Як граціозно вирішити це питання пам’яті?


10

У мене стандартний ноутбук для Linux (тестування Debian), з розділом swap.

Я роблю з цим багато експериментів. Деякі з них справді голодні по пам'яті, і те, як Linux веде себе за замовчуванням, є проблемою для мене ... Наведемо дурний приклад:

  1. Сядьте перед ноутбуком
  2. Відкрийте термінал
  3. Введіть python, тодіa = [0]*100000000

Зараз великі шанси, що у вас не вистачить оперативної пам’яті, щоб обробити цей великий список. Linux заповнить оперативну пам’ять, потім поміняється свопом, і через пару хвилин вбивця OOM буде спрацьовано і вб'є (майже) випадкові сервіси і, сподіваємось, якщо ви вчасно натиснете Ctrl + C python, і якщо термінал як і раніше фокус, комп'ютер знову стане чуйним.

Я хотів би застосувати деякі обмеження пам'яті, щоб уникнути небажаної заміни та відмовитись від процесу на виділення більше пам'яті, ніж у мене (в оперативній пам'яті). Якщо потреба в пам'яті знаходиться нижче певної межі або запитується коренем, то просто вбийте самий голодний процес будь-якого користувача, крім root.

ulimit -Sv [mem] Я чую ззаду!

Хо-хо! "Використовуйте cgroupsчерез cgexec!" хтось каже в першому ряду!

Так, ви праві: це дійсно дуже хороші рішення. Але:

  • Вони не застосовуються у загальній системі
  • Ліміти встановлюються на процес
  • Ліміти є статичними, не враховуючи реальну кількість вільної оперативної пам’яті (AFAIK)
  • Тут і там вони кажуть, що це не дуже вдале рішення для забезпечення жорстких обмежень.

Мені б хотілося, щоб ядро ​​сказало: "Ви належите до користувача foo (а не root), ви використовуєте багато пам'яті, і у нас не вистачить пам'яті. Вибачте чувак ... помирайте зараз!"

Або: "Що, до біса, ти робиш? Вам потрібно x MB, і доступно лише y MB. Так, SWAP порожній, але ви не збираєтесь використовувати SWAP для вашої брудної роботи, чи не так? Ні, я сказала ні! Ні пам'яті для тебе! Якщо ти будеш наполягати, ти помреш! "


2
У цій статті вже описаний алгоритм, який допомагає вбивці OOM вибрати правильний процес. Зміна /proc/sys/vm/overcommit_memoryвпливає на поведінку ядра при низькій пам'яті.
jofel

1
Так, але overcommit_memoryспеціальний файл використовує оперативну пам’ять + SWAP в якості корисної пам'яті. Я все ще збираюся поміняти

1
Вам також потрібно пояснити, як це не дублікат цього: unix.stackexchange.com/questions/34334/…, що суперечить вам WRT-групам та окремим користувачам. PS. Якщо ви не хочете поміняти місцями, вимкніть його .
goldilocks

1
Я хочу обмінятися! Я хочу в сплячку, я хочу, щоб невикористані байти не зберігалися! Але я не хочу, щоб використовувані байти зберігалися там. Щодо посилання ulimits- це погана ідея, як це показано майже скрізь, оскільки це обмеження за процес… Я ви знаєте :) Про cgroupsце, безумовно, краще, але не вистачає чогось більш загального: я говорю про свій ноутбук, але я також володіти сервером "обчислення", яким нам ділитися троє. Якщо я буду застосовувати такі обмеження за користувачем, я буду обмежений найгіршим сценарієм, чи не так?

1
cgroups дійсно застосовуються до будь-якого процесу, який ви вирішите - перекладіть всі процеси користувача в окрему групу, і він повинен робити те, що ви хочете.
петерф

Відповіді:


4

Хтось запропонував вам почути cgroups. Ну, спробуйте шукати той напрямок, оскільки він може вам забезпечити:

  • застосовано до групи завдань, яку ви обрали (таким чином, не по всій системі, але ні за один процес)
  • обмеження встановлюються для групи
  • межі статичні
  • вони можуть застосовувати жорсткий ліміт на пам'ять та / або пам'ять + своп

Щось подібне може наблизити вас до своїх цілей :

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

Це говорить про те, що завдання під цією групою можуть використовувати максимум 50 М пам'яті і 50 М пам'яті + своп, тому коли пам'ять заповнена, вона не буде мінятися, але якщо пам'ять не повна і деякі дані можуть бути відображені в поміняти, це може бути дозволено.

Ось уривок із документації на пам'ять групи :

Використовуючи ліміт memsw, ви можете уникнути системного OOM, який може бути викликаний дефіцитом свопу.


Ще не зовсім те, що я очікував. Але різниця між тим, що я очікую від реальності, часто досить велика :) У цьому випадку я хотів бути впевненим, що я не пропустив нічого, як overcommit_memoryзмінна ядро. Дякую всім.

0

Я часто стикаюся з тією ж проблемою. Мій загальний робочий процес включає важкі обчислення в MATLAB. Інколи я необачно намагаюся виділити нову змінну, що перевищує об'єм доступної пам'яті. Система зависає, і мені зазвичай доводиться важко перезавантажувати машину, щоб повернутися до роботи. : P

У моєму випадку, і це звучить так само, як і у вашому, я не так переймався обмеженням кількості пам'яті, яку MATLAB використовує, до статичної кількості - мені було цікаво не мати замороженої машини, і я був готовий пожертвувати своїм процесом MATLAB щоб зберегти чутливість системи.

Натхненний відповіддю на цю публікацію , я написав такий сценарій (я назвав його 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

Цей скрипт перевіряє кожну секунду на відсотковий обсяг вільної пам'яті. Коли система закінчується, ваш pid "козла відпущення" (переданий як аргумент до сценарію) вбивається.

Не коригуючи пріоритет (приємність) сценарію, знадобилося приблизно 10-20 секунд, щоб козла жертви вбити, але він все одно працював. Запуск сценарію з негативним пріоритетом призвів до миттєвого вбивства після порушення (11916 у цьому прикладі - це та інше, яке я хочу вбити, якщо у мене закінчиться пам'ять):

sudo nice -n -5 bash watch_memory.sh 11916
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.