Автоматично вбивати процес, якщо він перевищує задану кількість оперативної пам’яті


13

Я працюю над масштабними наборами даних. Під час тестування нового програмного забезпечення сценарій іноді підкрадається до мене, швидко захопить всю доступну оперативну пам’ять і зробить мій робочий стіл непридатним. Я хотів би встановити ліміт оперативної пам’яті для процесу, так що якщо він перевищить цю суму, він буде знищений автоматично. Мовне рішення, певно, не працюватиме, оскільки я використовую всілякі різні інструменти (R, Perl, Python, Bash тощо).

Так чи є якийсь монітор процесу, який дозволить мені встановити порогову кількість оперативної пам’яті та автоматично вбити процес, якщо він використовує більше?



@ Uri: На цій темі я отримав лише часткову (лише для частини процесора мого запитання) - і не оптимальну - відповідь. Він запитує про використання оперативної пам'яті.
Кріскін

1
Урі, у цій нитці повний брак корисних ідей. Опублікувати посилання на нього не особливо корисно.
chrisamiller

1
Hrmm - ця суперусерська нитка, здається, має розумну пропозицію, використовуючи ulimit: superuser.com/questions/66383/restrict-ram-for-user-or-process
chrisamiller

Відповіді:


11

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

https://github.com/pshved/timeout

Я в першу чергу даю цей постріл, але вітаю Амея Джа за гарну відповідь. Я перевірю це, якщо цей мені не вдасться.


5
+1 Відповідь на власне питання - це нормально !
Том Броссман

10

Я б настійно радив цього не робити . Як запропонував @chrisamiller, встановлення ulimit обмежить оперативну пам’ять, доступну з процесом.

Але все ж якщо ви наполягаєте, то дотримуйтесь цієї процедури.

  1. Збережіть такий сценарій як killif.sh:

    #!/bin/sh
    
    if [ $# -ne 2 ];
    then
        echo "Invalid number of arguments"
        exit 0
    fi
    
    while true;
    do
        SIZE=$(pmap $1|grep total|grep -o "[0-9]*")
        SIZE=${SIZE%%K*}
        SIZEMB=$((SIZE/1024))
        echo "Process id =$1 Size = $SIZEMB MB"
        if [ $SIZEMB -gt $2 ]; then
            printf "SIZE has exceeded.\nKilling the process......"
            kill -9 "$1"
            echo "Killed the process"
            exit 0
        else
            echo "SIZE has not yet exceeding"
        fi
    
        sleep 10
    done
  2. Тепер зробіть його виконуваним.

    chmod +x killif.sh
    
  3. Тепер запустіть цей скрипт на терміналі. Замініть PROCIDфактичним ідентифікатором процесу та SIZEрозміром у МБ.

    ./killif.sh PROCID SIZE
    

    Наприклад:

    ./killif.sh 132451 100
    

    Якщо SIZE100, то процес буде знищений, якщо його використання оперативної пам'яті перевищить 100 Мб

Увага: Ви знаєте, що намагаєтесь зробити. Процес вбивства не є хорошою ідеєю. Якщо в цьому процесі є якась команда відключення або зупинки, відредагуйте скрипт і замініть kill -9команду на цю shutdownкоманду.


я б розглядав, як там спати мало, наприклад, спати 0,5 ...
Денверко

@George Edison Як це зробили. Коли я намагався вставити, він давав мені дивно відформатований текст. Денверко: Де б ви хотіли спати. Я вже поклав сон на 10 секунд у циклі "час"
Amey Jah

2
Дякую за рішення, як зазначено нижче, я можу це перевірити. Чому все-таки всі страшні попередження про процеси вбивства? Програмне забезпечення управління кластерами (LSF, PBS та ін.) Робить це весь час, коли процес перевищує кількість необхідних йому ресурсів, не маючи тяжких наслідків. Я погоджуюся, що це не гарне рішення для нових користувачів, які, ймовірно, неправильно його застосовують, але в правильних обставинах це може бути досить корисним.
chrisamiller

@chrisamiller Я висунув попередження для майбутніх читачів. У вашому випадку ви знаєте наслідки, але майбутній читач цієї публікації може не знати про такі наслідки.
Amey Jah

2
Чи можете ви детальніше розібратися, чому цього не зробити?
jterm

2

Спробуйте prlimitінструмент, з util-linuxупаковки. Він запускає програму з обмеженням ресурсів. Він використовує prlimitсистемний виклик для встановлення лімітів, які потім виконуються чисто ядром.

Ви можете налаштувати 16 обмежень, включаючи:

  • максимальна кількість часу процесора в секундах
  • максимальна кількість користувачів процесів
  • максимальний розмір набору резидентів ("використана пам'ять")
  • максимальний розмір, який може зафіксуватися в пам'яті
  • розмір віртуальної пам'яті
  • максимальна кількість відкритих файлів
  • максимальна кількість блокувань файлів
  • максимальна кількість відкладених сигналів
  • максимум байтів у черзі повідомлень POSIX

0

Це було занадто великим, щоб відповідати коментарям. Я змінив оригінальний сценарій Amey, щоб він включав a pgrep, тому замість того, щоб вручну вводити ідентифікатор процесу, ви можете просто виключити ім'я. Наприклад, ./killIf.sh chrome 4000вбиває будь-який хромований процес, який перевищує 4 Гб у використанні пам'яті.

#!/bin/sh

# $1 is process name
# $2 is memory limit in MB

if [ $# -ne 2 ];
then
    echo "Invalid number of arguments"
    exit 0
fi

while true;
do
    pgrep "$1" | while read -r procId;
    do
        SIZE=$(pmap $procId | grep total | grep -o "[0-9]*")
        SIZE=${SIZE%%K*}
        SIZEMB=$((SIZE/1024))
        echo "Process id = $procId Size = $SIZEMB MB"
        if [ $SIZEMB -gt $2 ]; then
            printf "SIZE has exceeded.\nKilling the process......"
            kill -9 "$procId"
            echo "Killed the process"
            exit 0
        else
            echo "SIZE has not yet exceeding"
        fi
    done

    sleep 1
done

Будьте обережні, щоб вибрати вузьку греп-рядок і достатньо великий обсяг пам'яті, щоб не вбивати зайвих процесів.

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