特定のRAM容量を超えた場合にプロセスを自動的に強制終了します


12

大規模なデータセットに取り組んでいます。新しいソフトウェアをテストするとき、スクリプトが時々忍び寄り、使用可能なすべてのRAMをすばやく取得し、デスクトップを使用できなくします。プロセスのRAM制限を設定して、その量を超えると自動的に強制終了されるようにしたいのですが。言語固有のソリューションはおそらく機能しません。さまざまなツール(R、Perl、Python、Bashなど)を使用しているからです。

だから、RAMのしきい値量を設定し、それ以上を使用する場合に自動的にプロセスを強制終了させるようなプロセスモニターがありますか?



@ Uri:そのスレッドでは、部分的(私の質問のCPU部分のみ)しか得られませんでした-最適ではありません-答え。彼はRAMの使用について尋ねます。
クリスキン

1
ウリ、そのスレッドには有用なアイデアがまったくありません。それへのリンクを投稿することは特に有用ではありません。
chrisamiller

1
うーん-このスーパーユーザースレッドはulimitを使用して合理的な提案があるようです:superuser.com/questions/66383/restrict-ram-for-user-or-process
chrisamiller

回答:


11

私は彼自身の質問に答える人になるのは嫌いですが、今朝、素敵な小さなユーティリティに包まれた別の方法を見つけました。CPU時間またはメモリ消費を制限します。

https://github.com/pshved/timeout

最初にこれを試してみますが、いい答えを求めてアミー・ジャーに賛成です。これが私に失敗したら私はそれをチェックします。


5
+1あなた自身の質問に答えても大丈夫です
トムブロスマン

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およびSIZEMB単位のサイズに置き換えます。

    ./killif.sh PROCID SIZE
    

    例えば:

    ./killif.sh 132451 100
    

    もしSIZEそのRAMの使用量が100メガバイトを超えるまでになった場合100個のプロセスが強制終了されますされています。

注意:あなたは何をしようとしているのか知っています。プロセスを強制終了することはお勧めできません。そのプロセスにシャットダウンまたは停止コマンドがある場合、スクリプトを編集し、kill -9コマンドをそのshutdownコマンドに置き換えます。


私はそこに少し睡眠をとることを検討します、例えば、睡眠0.5 ...
Denwerko

@George Edisonどうやってそれをしましたか。貼り付けようとしたときに、奇妙な形式のテキストが表示されました。デンウェルコ:どこで眠りたいですか。私はすでに、whileループで10秒のスリープを入れています
Ameyジャー

2
以下に示すように、解決策のおかげで、私はそれをチェックアウトすることがあります。しかし、プロセスを強制終了することについてのすべての恐ろしい警告がなぜですか?クラスター管理ソフトウェア(LSF、PBSなど)は、プロセスが要求したリソースの量を超えると、これを常に行います。これは、誤って適用する可能性が高い新規ユーザーにとっては良い解決策ではないことに同意しますが、適切な状況では、これは非常に便利です。
chrisamiller

@chrisamiller今後の読者に警告を出しました。あなたの場合、あなたはその意味を知っていますが、この投稿の今後の読者はそのような意味を知らないかもしれません。
アミージャー

2
なぜそうしないのか詳しく説明していただけますか?
jterm

2

パッケージprlimitからツールを試してくださいutil-linux。リソース制限のあるプログラムを実行します。prlimitシステムコールを使用して制限を設定します。制限は、カーネルによって強制的に適用されます。

以下を含む16の制限を構成できます。

  • 秒単位のCPU時間の最大量
  • ユーザープロセスの最大数
  • 常駐セットの最大サイズ(「使用済みメモリ」)
  • プロセスがメモリにロックできる最大サイズ
  • 仮想メモリのサイズ
  • 開いているファイルの最大数
  • ファイルロックの最大数
  • 保留信号の最大数
  • POSIXメッセージキューの最大バイト

0

これは大きすぎてコメントに収まりません。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文字列と十分に大きいメモリ制限を選択するように注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.