Dalším způsobem, jak to omezit, je použití řídicích skupin Linuxu. To je zvláště užitečné, pokud chcete omezit procesem (nebo skupinou procesů) alokaci fyzické paměti odlišně od virtuální paměti. Například:
cgcreate -g memory:myGroup
echo 500M > /sys/fs/cgroup/memory/myGroup/memory.limit_in_bytes
echo 5G > /sys/fs/cgroup/memory/myGroup/memory.memsw.limit_in_bytes
vytvoří kontrolní skupinu s názvem myGroup
, omezte sadu procesů spuštěných pod myGroup
až 500 MB fyzické paměti s memory.limit_in_bytes
a až 5000 MB fyzické a odkládací paměti spolu s memory.memsw.limit_in_bytes
.Více informací o těchto možnostech naleznete zde:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/resource_management_guide/sec-memory
Chcete-li spustit proces v řídicí skupině:
cgexec -g memory:myGroup pdftoppm
Všimněte si, že na moderní distribuci Ubuntu tento příklad vyžaduje instalaci cgroup-bin
balíček a úprava /etc/default/grub
pro změnu GRUB_CMDLINE_LINUX_DEFAULT
komu:
GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1"
a poté spuštění sudo update-grub
a restartování, aby se zavedlo s novými parametry zavádění jádra.
Pokud váš proces nevytváří více potomků, které spotřebovávají nejvíce paměti, můžete použít setrlimit
funkce. Běžnějším uživatelským rozhraním je použití ulimit
příkaz shellu:
$ ulimit -Sv 500000 # Set ~500 mb limit
$ pdftoppm ...
Tím se omezí pouze „virtuální“ paměť vašeho procesu, vezme se v úvahu – a omezí – paměť, kterou vyvolávaný proces sdílí s jinými procesy, a paměť mapovaná, ale ne rezervovaná (například velká halda Java). Přesto je virtuální paměť nejbližší aproximací pro procesy, které rostou opravdu velké, takže uvedené chyby jsou nevýznamné.
Pokud váš program plodí potomky a jsou to oni, kdo alokuje paměť, stává se složitějším a měli byste psát pomocné skripty pro spouštění procesů pod vaší kontrolou. Napsal jsem na svůj blog, proč a jak.
S ulimitem jsou nějaké problémy. Zde je užitečná četba na téma:Omezení spotřeby času a paměti programu v Linuxu, což vede k nástroji timeout, který vám umožňuje ukotvit proces (a jeho větve) podle spotřeby času nebo paměti.
Nástroj časového limitu vyžaduje Perl 5+ a /proc
připojený souborový systém. Poté nástroj zkopírujete např. /usr/local/bin
takhle:
curl https://raw.githubusercontent.com/pshved/timeout/master/timeout | \
sudo tee /usr/local/bin/timeout && sudo chmod 755 /usr/local/bin/timeout
Poté můžete svůj proces „uzavřet“ spotřebou paměti jako ve vaší otázce:
timeout -m 500 pdftoppm Sample.pdf
Alternativně můžete použít -t <seconds>
a -x <hertz>
k omezení procesu podle času nebo omezení CPU.
Tento nástroj funguje tak, že několikrát za sekundu kontroluje, zda vytvořený proces nepřekročil své nastavené hranice. To znamená, že ve skutečnosti existuje malé okno, kde by proces potenciálně mohl předplatit, než si všimne vypršení časového limitu a proces ukončí.
Správnější přístup by tedy pravděpodobně zahrnoval cgroups, ale to je mnohem náročnější na nastavení, i když byste použili Docker nebo runC, které mimo jiné nabízejí uživatelsky přívětivější abstrakci kolem cgroups.