Non sono sicuro che questo risponda alla tua domanda, ma ho trovato questo script perl che afferma di fare esattamente quello che stai cercando. Lo script implementa il proprio sistema per far rispettare i limiti risvegliando e controllando l'utilizzo delle risorse del processo e dei suoi figli. Sembra essere ben documentato e spiegato, ed è stato aggiornato di recente.
Come ha detto slm nel suo commento, anche i cgroup possono essere usati per questo. Potrebbe essere necessario installare le utilità per la gestione dei cgroup, supponendo che tu sia su Linux dovresti cercare libcgroups
.
sudo cgcreate -t $USER:$USER -a $USER:$USER -g memory:myGroup
Assicurati che $USER
è il tuo utente.
Il tuo utente dovrebbe quindi avere accesso alle impostazioni di memoria del cgroup in /sys/fs/cgroup/memory/myGroup
.
Puoi quindi impostare il limite a, diciamo, 500 MB, in questo modo:
echo 500000000 > /sys/fs/cgroup/memory/myGroup/memory.limit_in_bytes
Ora lanciamo Vim:
cgexec -g memory:myGroup vim
Il processo vim e tutti i suoi figli dovrebbero ora essere limitati all'utilizzo di 500 MB di RAM. Tuttavia , penso che questo limite si applichi solo alla RAM e non allo scambio. Una volta che i processi raggiungono il limite, inizieranno a scambiarsi. Non sono sicuro che tu possa aggirare questo problema, non riesco a trovare un modo per limitare l'utilizzo dello swap usando cgroups.
https://unix.stackexchange.com/a/536046/4319:
Su qualsiasi distribuzione basata su systemd puoi anche usare cgroups indirettamente tramite systemd-run. Per esempio. per il tuo caso di limitazione pdftoppm
a 500M di RAM, usa:
systemd-run --scope -p MemoryLimit=500M pdftoppm
...
Ho creato uno script che fa questo, usando cgmanager che è usato in Ubuntu. Un vantaggio è che questo non richiede l'accesso root. Tieni presente che la gestione di cgroup è un po' specifica della distribuzione, quindi non so se funziona su distribuzioni che utilizzano la gestione di cgroup di systemd.
#!/bin/sh
set -eu
if [ "$#" -lt 2 ]
then
echo Usage: `basename $0` "<limit> <command>..."
exit 1
fi
limit="$1"
shift
cgname="limitmem_$$"
echo "limiting memory to $limit (cgroup $cgname) for command [email protected]"
cgm create memory "$cgname" >/dev/null
cgm setvalue memory "$cgname" memory.limit_in_bytes "$limit" >/dev/null
# try also limiting swap usage, but this fails if the system has no swap
cgm setvalue memory "$cgname" memsw.limit_in_bytes "$limit" >/dev/null 2>&1 || true
# spawn subshell to run in the cgroup
set +e
(
set -e
cgm movepid memory "$cgname" `sh -c 'echo $PPID'` > /dev/null
exec "[email protected]"
)
# grab exit code
exitcode=`echo $?`
set -e
echo -n "peak memory used: "
cgm getvalue memory "$cgname" memory.max_usage_in_bytes | tail -1 | cut -f2 -d\"
cgm remove memory "$cgname" >/dev/null
exit $exitcode
utilizzo:salva come limitmem
nel tuo percorso e renderlo eseguibile. Quindi esegui ad es. limitmem 1G command...
. Questo limita la memoria effettivamente utilizzata. Se questo viene raggiunto, il killer OOM ucciderà il processo o uno dei suoi figli, ma non qualcosa di casuale che non ha nulla a che fare con questo comando.