Nejsem si jistý, zda to odpovídá na vaši otázku, ale našel jsem tento skript v perlu, který tvrdí, že dělá přesně to, co hledáte. Skript implementuje svůj vlastní systém pro vynucení limitů tím, že se probudí a zkontroluje využití zdrojů procesu a jeho potomků. Zdá se, že je dobře zdokumentován a vysvětlen a nedávno byl aktualizován.
Jak uvedl slm ve svém komentáři, lze k tomu použít i cgroups. Možná budete muset nainstalovat nástroje pro správu cgroups, za předpokladu, že používáte Linux, měli byste hledat libcgroups
.
sudo cgcreate -t $USER:$USER -a $USER:$USER -g memory:myGroup
Ujistěte se, že $USER
je váš uživatel.
Váš uživatel by pak měl mít přístup k nastavení paměti cgroup v /sys/fs/cgroup/memory/myGroup
.
Poté můžete nastavit limit na, řekněme 500 MB, takto:
echo 500000000 > /sys/fs/cgroup/memory/myGroup/memory.limit_in_bytes
Nyní spustíme Vim:
cgexec -g memory:myGroup vim
Proces vim a všechny jeho potomky by nyní měly být omezeny na použití 500 MB RAM. Nicméně , myslím, že tento limit platí pouze pro RAM a ne swap. Jakmile procesy dosáhnou limitu, začnou se vyměňovat. Nejsem si jistý, jestli to dokážete obejít, nemohu najít způsob, jak omezit používání swapu pomocí cgroups.
https://unix.stackexchange.com/a/536046/4319:
V jakémkoli distribuci založeném na systemd můžete také použít cgroups nepřímo prostřednictvím systemd-run. Např. pro váš případ omezení pdftoppm
do 500M paměti RAM, použijte:
systemd-run --scope -p MemoryLimit=500M pdftoppm
...
Vytvořil jsem skript, který to dělá, pomocí cgmanageru, který se používá v Ubuntu. Jednou z výhod je, že to nevyžaduje přístup root. Všimněte si, že správa cgroup je trochu specifická pro distribuci, takže nevím, jestli to funguje na distribucích, které používají správu cgroup 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
použití:uložte jako limitmem
ve vaší cestě a udělejte jej spustitelným. Poté spusťte např. limitmem 1G command...
. To omezuje skutečně používanou paměť. Pokud se toho dosáhne, zabiják OOM zabije proces nebo jedno z jeho potomků, ale ne něco náhodného, co nemá nic společného s tímto příkazem.