Termina automaticamente un processo se supera una determinata quantità di RAM


12

Lavoro su set di dati su larga scala. Durante il test di un nuovo software, a volte uno script si insinua su di me, acquisisce rapidamente tutta la RAM disponibile e rende il mio desktop inutilizzabile. Vorrei un modo per impostare un limite di RAM per un processo in modo che se supera tale importo, verrà automaticamente ucciso. Una soluzione specifica per la lingua probabilmente non funzionerà, poiché utilizzo tutti i tipi di strumenti diversi (R, Perl, Python, Bash, ecc.).

Quindi esiste una sorta di monitor di processo che mi permetterà di impostare una soglia di RAM e di uccidere automaticamente un processo se ne utilizza di più?



@ Uri: in quel thread ho ottenuto solo una risposta parziale (solo per la parte cpu della mia domanda) - e non ottimale. Chiede sull'utilizzo della RAM.
Chriskin,

1
Uri, c'è una completa mancanza di idee utili in quel thread. Pubblicare un link non è particolarmente utile.
chrisamiller,

1
Hrmm - questo thread superutente sembra avere un suggerimento ragionevole usando ulimit: superuser.com/questions/66383/restrict-ram-for-user-or-process
chrisamiller

Risposte:


11

Odio essere il ragazzo che risponde alla sua stessa domanda, ma stamattina ho trovato un metodo alternativo, racchiuso in una piccola utilità. Limita il tempo della CPU o il consumo di memoria:

https://github.com/pshved/timeout

Per prima cosa sto dando a questo uno, ma voti ad Amey Jah per la bella risposta. Lo controllerò se questo non mi riesce.


5
+1 Rispondere alla tua domanda è OK !
Tom Brossman,

10

Consiglio vivamente di non farlo . Come suggerito da @chrisamiller, l'impostazione di ulimit limiterà la RAM disponibile con il processo.

Tuttavia, se insisti, segui questa procedura.

  1. Salva il seguente script come 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. Ora rendilo eseguibile.

    chmod +x killif.sh
    
  3. Ora esegui questo script sul terminale. Sostituire PROCIDcon l'ID processo effettivo e SIZEcon le dimensioni in MB.

    ./killif.sh PROCID SIZE
    

    Per esempio:

    ./killif.sh 132451 100
    

    Se SIZEè 100, il processo verrà interrotto se l'utilizzo della RAM supera i 100 MB.

Attenzione: sai cosa stai cercando di fare. Il processo di uccisione non è una buona idea. Se quel processo ha un comando di arresto o arresto, modifica lo script e sostituisci il kill -9comando con quel shutdowncomando.


prenderei in considerazione di dormire poco, ad esempio dormire 0,5 ...
Denwerko

@ George Edison Come hai fatto. Quando ho provato a incollare, mi stava dando un testo formattato in modo strano. Denwerko: Dove ti piacerebbe mettere il sonno. Ho già dormito 10 secondi nel ciclo while
Amey Jah,

2
Grazie per la soluzione, come indicato di seguito, posso verificarlo. Perché tutti i terribili avvertimenti sui processi di uccisione? Il software di gestione dei cluster (LSF, PBS e altri) lo fa sempre quando un processo supera la quantità di risorse richiesta, senza conseguenze disastrose. Sono d'accordo che questa non è una buona soluzione per i nuovi utenti che potrebbero applicarla in modo errato, ma nelle giuste circostanze, questo può essere abbastanza utile.
Chrisamiller,

@chrisamiller Ho messo in guardia per i futuri lettori. Nel tuo caso, conosci le implicazioni ma il futuro lettore di questo post potrebbe non essere consapevole di tali implicazioni.
Amey Jah,

2
Puoi approfondire perché non farlo?
jterm,

2

Prova lo prlimitstrumento, dal util-linuxpacchetto. Esegue un programma con limiti di risorse. Usa la prlimitchiamata di sistema per impostare i limiti, che vengono poi applicati esclusivamente dal kernel.

Puoi configurare 16 limiti, tra cui:

  • quantità massima di tempo della CPU in secondi
  • numero massimo di processi utente
  • dimensione massima impostata per il residente ("memoria utilizzata")
  • dimensione massima che un processo può bloccare in memoria
  • dimensione della memoria virtuale
  • numero massimo di file aperti
  • numero massimo di blocchi di file
  • numero massimo di segnali in sospeso
  • numero massimo di byte nelle code dei messaggi POSIX

0

Questo era troppo grande per adattarsi a un commento. Ho modificato lo script originale di Amey per includere a pgrep, quindi invece di inserire manualmente l'id del processo, puoi semplicemente escluderlo per nome. Ad esempio, ./killIf.sh chrome 4000uccide qualsiasi processo Chrome che supera i 4 GB nell'utilizzo della memoria.

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

Fare attenzione a selezionare una stringa grep stretta e un limite di memoria abbastanza grande da non uccidere inutilmente processi involontari.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.