如果超过给定的 RAM 量,则自动终止进程

如果超过给定的 RAM 量,则自动终止进程

我处理大规模数据集。在测试新软件时,脚本有时会悄悄出现,快速占用所有可用 RAM,导致我的桌面无法使用。我希望找到一种方法来为进程设置 RAM 限制,这样如果进程超过该限制,就会自动终止进程。特定语言的解决方案可能行不通,因为我使用各种不同的工具(R、Perl、Python、Bash 等)。

那么是否存在某种进程监视器,可以让我设置 RAM 的阈值,并在某个进程使用了​​过多的 RAM 时自动终止它?

答案1

我强烈建议不要这样做。正如 @chrisamiller 所建议的,设置 ulimit 将限制进程可用的 RAM。

但如果您仍坚持,请遵循此程序。

  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用实际进程 ID 和SIZEMB 大小替换。

    ./killif.sh PROCID SIZE
    

    例如:

    ./killif.sh 132451 100
    

    如果SIZE是 100,那么当进程的 RAM 使用量超过 100 MB 时,进程将被终止。

警告:您知道自己想做什么。终止进程并不是一个好主意。如果该进程有任何关闭或停止命令,则编辑脚本并kill -9用该shutdown命令替换命令。

答案2

我不喜欢自己回答问题,但今天早上我发现了一种替代方法,它被包装成一个不错的小实用程序。它将限制 CPU 时间或内存消耗:

https://github.com/pshved/timeout

我首先尝试了一下这个,但为 Amey Jah 的好答案点赞。如果这个方法不成功,我会检查一下。

答案3

尝试使用软件包prlimit中的工具util-linux。它运行一个具有资源限制的程序。它使用prlimit系统调用来设置限制,然后仅由内核执行。

您可以配置 16 个限制,其中包括:

  • 最大 CPU 时间(秒)
  • 最大用户进程数
  • 最大驻留集大小(“已用内存”)
  • 进程可以锁定到内存的最大大小
  • 虚拟内存的大小
  • 最大打开文件数
  • 最大文件锁数量
  • 最大待处理信号数
  • POSIX 消息队列中的最大字节数

答案4

这太大了,无法容纳评论。我修改了 Amey 的原始脚本以包含pgrep,因此您不必手动输入进程 ID,只需按名称排除即可。例如,./killIf.sh chrome 4000杀死任何内存使用量超过 4GB 的 chrome 进程。

#!/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 字符串和足够大的内存限制,以免不必要地终止非预期的进程。

相关内容