주어진 RAM 양을 초과하면 프로세스 자동 종료


13

대규모 데이터 세트 작업을하고 있습니다. 새로운 소프트웨어를 테스트 할 때, 때때로 스크립트가 나에게 몰래 들어가서 사용 가능한 모든 RAM을 빠르게 잡고 내 데스크탑을 사용할 수 없게 만듭니다. 프로세스의 RAM 제한을 설정하여 해당 양을 초과하면 자동으로 종료되도록하는 방법을 원합니다. 모든 종류의 다른 도구 (R, Perl, Python, Bash 등)를 사용하기 때문에 언어 별 솔루션이 작동하지 않을 수 있습니다.

RAM의 임계 값을 설정하고 더 많이 사용하는 경우 프로세스를 자동으로 종료시킬 수있는 일종의 프로세스 모니터가 있습니까?



@ Uri : 그 스레드에서 나는 부분적 (내 질문의 CPU 부분에만 해당)을 얻었으며 최적은 아닙니다. 그는 RAM 사용에 대해 묻습니다.
Chriskin

1
Uri, 그 스레드에 유용한 아이디어가 완전히 부족합니다. 링크를 게시하는 것은 특별히 도움이되지 않습니다.
chrisamiller

1
Hrmm-이 수퍼 유저 스레드는 ulimit를 사용하여 합리적인 제안을하는 것 같습니다 : superuser.com/questions/66383/restrict-ram-for-user-or-process
chrisamiller

답변:


11

나는 자신의 질문에 대답하는 사람이 싫지만 오늘 아침에 멋진 작은 유틸리티에 싸인 대체 방법을 찾았습니다. CPU 시간 또는 메모리 소비를 제한합니다.

https://github.com/pshved/timeout

이 사진을 먼저 찍었지만 좋은 대답을 위해 Amey Jah에게 찬성합니다. 이것이 실패하면 확인해 보겠습니다.


5
+1 자신의 질문에 대답하는 것은 괜찮습니다 !
Tom Brossman

10

하지 말 것을 강력히 권합니다 . @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 SIZE와 크기 (MB)로 교체하십시오 .

    ./killif.sh PROCID SIZE
    

    예를 들면 다음과 같습니다.

    ./killif.sh 132451 100
    

    경우 SIZE의 RAM 사용량이 1백메가바이트 이상으로 상승하는 경우 100 개 다음 프로세스가 살해 될 것입니다.

주의 : 당신은 무엇을하려고하는지 알고 있습니다. 죽이는 과정은 좋지 않습니다. 해당 프로세스에 shutdown 또는 stop 명령이 있으면 스크립트를 편집하고 kill -9해당 shutdown명령으로 명령 을 바꿉니다.


예를 들어 수면 0.5와 같은 작은 수면을 고려하는 것이
좋습니다

@George Edison 어떻게 했어요? 붙여 넣을 때 이상한 형식의 텍스트가 표시되었습니다. Denwerko : 잠을 자고 싶은 곳. 나는 while 루프에서 10 초의 수면을 이미했다
Amey Jah

2
아래에 명시된 바와 같이 솔루션에 감사드립니다. 체크 아웃 할 수 있습니다. 하지만 프로세스를 죽이는 것에 대한 모든 경고가 왜 그렇습니까? 클러스터 관리 소프트웨어 (LSF, PBS 등)는 프로세스가 요청한 리소스의 양을 초과 할 때 항상 큰 결과를 초래하지 않습니다. 나는 이것이 잘못 적용될 가능성이있는 새로운 사용자에게는 좋은 해결책이 아니라는 데 동의하지만, 올바른 상황에서는 이것이 매우 유용 할 수 있습니다.
chrisamiller

@ chrisamiller 나는 미래의 독자들에게 경고했다. 귀하의 경우, 당신은 그 의미를 알고 있지만이 게시물의 미래 독자는 그러한 의미를 인식하지 못할 수도 있습니다.
Amey Jah

2
왜 안하는지 자세히 설명해 주시겠습니까?
jterm

2

패키지 prlimit에서 도구를 사용해보십시오 util-linux. 자원 제한이있는 프로그램을 실행합니다. prlimit시스템 호출을 사용하여 한계를 설정 한 다음 순전히 커널에 의해 적용됩니다.

다음을 포함하여 16 개의 제한을 구성 할 수 있습니다.

  • 최대 CPU 시간 (초)
  • 최대 사용자 프로세스 수
  • 최대 상주 세트 크기 ( "사용 된 메모리")
  • 프로세스가 메모리에 잠길 수있는 최대 크기
  • 가상 메모리 크기
  • 열린 파일의 최대 수
  • 최대 파일 잠금 수
  • 보류중인 최대 신호 수
  • POSIX 메시지 큐의 최대 바이트

0

댓글에 맞추기에는 너무 컸습니다. 을 포함하도록 Amey의 원래 스크립트를 수정 했으므로 pgrep프로세스 ID를 수동으로 입력하는 대신 이름으로 제외 할 수 있습니다. 예를 들어 ./killIf.sh chrome 4000메모리 사용량이 4GB를 초과하는 모든 크롬 프로세스를 종료합니다.

#!/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 문자열과 충분한 메모리 제한을 선택해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.