Beendet einen Prozess automatisch, wenn er eine bestimmte RAM-Größe überschreitet


12

Ich arbeite an umfangreichen Datensätzen. Beim Testen neuer Software schleicht sich manchmal ein Skript an mich heran, greift schnell auf den gesamten verfügbaren Arbeitsspeicher zu und macht meinen Desktop unbrauchbar. Ich möchte eine Möglichkeit, ein RAM-Limit für einen Prozess festzulegen, damit dieser automatisch beendet wird, wenn er diesen Wert überschreitet. Eine sprachspezifische Lösung wird wahrscheinlich nicht funktionieren, da ich alle möglichen Tools (R, Perl, Python, Bash usw.) verwende.

Gibt es also eine Art Prozessmonitor, mit dem ich einen Schwellenwert für den Arbeitsspeicher festlegen und einen Prozess automatisch beenden kann, wenn er mehr verwendet?



@Uri: Bei diesem Thread habe ich nur einen Teil (nur für den CPU-Teil meiner Frage) - und keine optimale - Antwort bekommen. Er fragt nach der RAM-Nutzung.
Chriskin

1
Uri, in diesem Thread fehlt es an nützlichen Ideen. Das Posten eines Links ist nicht besonders hilfreich.
Chrisamiller

1
Hrmm - das Superuser - Thread scheint ein vernünftiger Vorschlag zu haben ulimit: superuser.com/questions/66383/restrict-ram-for-user-or-process
chrisamiller

Antworten:


11

Ich hasse es, der Typ zu sein, der seine eigene Frage beantwortet, aber heute Morgen habe ich eine alternative Methode gefunden, die in ein nettes kleines Hilfsprogramm eingepackt ist. Es wird die CPU-Zeit oder den Speicherverbrauch begrenzen:

https://github.com/pshved/timeout

Ich versuche es zuerst, aber Amey Jah für die nette Antwort. Ich werde nachsehen, ob dieser Fehler bei mir auftritt.


5
+1 Die Beantwortung Ihrer eigenen Frage ist in Ordnung !
Tom Brossman

10

Ich würde dringend raten, es nicht zu tun . Wie von @chrisamiller vorgeschlagen, wird durch Festlegen von ulimit der für den Prozess verfügbare Arbeitsspeicher begrenzt.

Wenn Sie dennoch darauf bestehen, befolgen Sie dieses Verfahren.

  1. Speichern Sie das folgende Skript als 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. Nun mache es ausführbar.

    chmod +x killif.sh
    
  3. Führen Sie nun dieses Skript auf dem Terminal aus. Ersetzen Sie PROCIDdurch die tatsächliche Prozess-ID und SIZEdurch die Größe in MB.

    ./killif.sh PROCID SIZE
    

    Beispielsweise:

    ./killif.sh 132451 100
    

    Bei SIZE100 wird der Prozess abgebrochen, wenn die RAM-Auslastung mehr als 100 MB beträgt.

Achtung: Sie wissen, was Sie versuchen zu tun. Tötungsprozess ist keine gute Idee. Wenn dieser Prozess einen Befehl zum Herunterfahren oder Stoppen enthält, bearbeiten Sie das Skript und ersetzen Sie den kill -9Befehl durch diesen shutdownBefehl.


Ich würde überlegen, wenig Schlaf dort, zum Beispiel Schlaf 0,5 ...
Denwerko

@ George Edison Wie hast du das gemacht? Als ich versuchte einzufügen, gab es mir seltsam formatierten Text. Denwerko: Wo würdest du gerne schlafen? Ich habe in der while-Schleife bereits 10 Sekunden geschlafen
Amey Jah

2
Vielen Dank für die Lösung, wie unten angegeben, ich kann es überprüfen. Warum aber all die furchtbaren Warnungen vor Tötungsprozessen? Cluster-Management-Software (LSF, PBS usw.) erledigt dies immer dann, wenn ein Prozess die von ihm angeforderte Ressourcenmenge überschreitet, ohne schlimme Konsequenzen. Ich bin damit einverstanden, dass dies keine gute Lösung für neue Benutzer ist, die es wahrscheinlich falsch anwenden, aber unter den richtigen Umständen kann dies sehr nützlich sein.
Chrisamiller

@chrisamiller Ich habe eine Warnung für zukünftige Leser aufgestellt. In Ihrem Fall kennen Sie die Auswirkungen, aber zukünftige Leser dieses Beitrags sind sich dieser Auswirkungen möglicherweise nicht bewusst.
Amey Jah

2
Können Sie näher erläutern, warum Sie das nicht tun sollten?
jterm

2

Probieren Sie das prlimitTool aus der util-linuxPackung. Es wird ein Programm mit Ressourcenlimits ausgeführt. Es verwendet den prlimitSystemaufruf, um die Grenzwerte festzulegen, die dann nur vom Kernel erzwungen werden.

Sie können 16 Grenzwerte konfigurieren, darunter:

  • maximale CPU-Zeit in Sekunden
  • maximale Anzahl von Benutzerprozessen
  • maximale residente Set-Größe ("belegter Speicher")
  • Die maximale Größe, die ein Prozess im Speicher speichern kann
  • Größe des virtuellen Speichers
  • Maximale Anzahl geöffneter Dateien
  • maximale Anzahl von Dateisperren
  • maximale Anzahl anstehender Signale
  • Maximale Anzahl von Bytes in POSIX-Nachrichtenwarteschlangen

0

Das war zu groß für einen Kommentar. Ich habe Ameys ursprüngliches Skript dahingehend geändert, dass es ein einschließt. pgrepAnstatt die Prozess-ID manuell einzugeben, können Sie sie einfach nach Namen ausschließen. Beendet z. B. ./killIf.sh chrome 4000alle Chrome-Prozesse, deren Speichernutzung 4 GB überschreitet.

#!/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

Achten Sie darauf, eine schmale grep-Zeichenfolge und ein ausreichend großes Speicherlimit auszuwählen, um nicht unnötig unbeabsichtigte Prozesse zu beenden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.