Автоматически уничтожать процесс, если он превышает заданный объем оперативной памяти


12

Я работаю над крупномасштабными наборами данных. При тестировании нового программного обеспечения скрипт иногда подкрадывается ко мне, быстро захватывает всю доступную оперативную память и делает мой рабочий стол непригодным для использования. Я бы хотел, чтобы был установлен лимит оперативной памяти для процесса, чтобы, если он превышает это количество, он автоматически уничтожался. Решение для конкретного языка, вероятно, не будет работать, так как я использую всевозможные инструменты (R, Perl, Python, Bash и т. Д.).

Так есть ли какой-нибудь монитор процесса, который позволит мне установить пороговое количество оперативной памяти и автоматически убить процесс, если он будет использовать больше?



@ Uri: В этой теме я получил только частичный (только для части моего вопроса) - и не оптимальный - ответ. Он спрашивает об использовании оперативной памяти.
Chriskin

1
Ури, в этой ветке полное отсутствие полезных идей. Размещение ссылки на него не особенно полезно.
chrisamiller

1
Хммм - у этого суперпользовательского потока, кажется, есть разумное предложение с использованием 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
    

    Если SIZEустановлено значение 100, то процесс будет остановлен, если его использование ОЗУ превысит 100 МБ.

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



@ Джордж Эдисон Как ты это сделал. Когда я пытался вставить, это дало мне странно отформатированный текст. Денверко: Куда бы ты хотел поспать? Я уже поставил на 10 секунд сон в то время как цикл
Amey Jah

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

@ chrisamiller Я предупредил будущих читателей. В вашем случае вы знаете последствия, но будущий читатель этого поста может не знать о таких последствиях.
Эми Джа

2
Можете ли вы уточнить, почему бы не сделать это?
17

2

Попробуйте prlimitинструмент из util-linuxпакета. Он запускает программу с ограниченными ресурсами. Он использует prlimitсистемный вызов для установки ограничений, которые затем применяются исключительно ядром.

Вы можете настроить 16 ограничений, в том числе:

  • максимальное количество процессорного времени в секундах
  • максимальное количество пользовательских процессов
  • максимальный размер резидентного набора («используемая память»)
  • максимальный размер, который процесс может заблокировать в памяти
  • размер виртуальной памяти
  • максимальное количество открытых файлов
  • максимальное количество блокировок файлов
  • максимальное количество ожидающих сигналов
  • максимальное количество байтов в очередях сообщений POSIX

0

Это было слишком велико, чтобы вместить комментарий. Я изменил оригинальный скрипт Amey, чтобы включить в него pgrep, поэтому вместо того, чтобы вручную вводить идентификатор процесса, вы можете просто исключить его по имени. Например, ./killIf.sh chrome 4000убивает любой процесс chrome, который превышает 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

Будьте внимательны, выбирая узкую строку grep и достаточно большой лимит памяти, чтобы избежать ненужного уничтожения непреднамеренных процессов.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.