Eine andere Möglichkeit, dies einzuschränken, besteht darin, die Kontrollgruppen von Linux zu verwenden. Dies ist besonders nützlich, wenn Sie die Zuweisung von physischem Speicher eines Prozesses (oder einer Gruppe von Prozessen) getrennt vom virtuellen Speicher einschränken möchten. Zum Beispiel:
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
erstellt eine Kontrollgruppe namens myGroup
, begrenzen Sie den Satz von Prozessen, die unter myGroup
ausgeführt werden bis zu 500 MB physischer Speicher mit memory.limit_in_bytes
und bis zu 5000 MB physischer und Auslagerungsspeicher zusammen mit memory.memsw.limit_in_bytes
.Weitere Informationen zu diesen Optionen finden Sie hier:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/resource_management_guide/sec-memory
So führen Sie einen Prozess unter der Kontrollgruppe aus:
cgexec -g memory:myGroup pdftoppm
Beachten Sie, dass dieses Beispiel auf einer modernen Ubuntu-Distribution die Installation von cgroup-bin
erfordert Paket und Bearbeiten von /etc/default/grub
um GRUB_CMDLINE_LINUX_DEFAULT
zu ändern zu:
GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1"
und dann sudo update-grub
ausführen und Neustart, um mit den neuen Kernel-Boot-Parametern zu booten.
Wenn Ihr Prozess nicht mehr Kinder hervorbringt, die den meisten Speicher verbrauchen, können Sie setrlimit
verwenden Funktion. Eine gebräuchlichere Benutzeroberfläche dafür ist die Verwendung von ulimit
Kommando der Shell:
$ ulimit -Sv 500000 # Set ~500 mb limit
$ pdftoppm ...
Dadurch wird nur der "virtuelle" Speicher Ihres Prozesses begrenzt, wobei der Speicher, den der aufgerufene Prozess mit anderen Prozessen teilt, und der zugeordnete, aber nicht reservierte Speicher (z. B. der große Heap von Java) berücksichtigt und begrenzt wird. Dennoch ist der virtuelle Speicher die beste Annäherung für Prozesse, die wirklich groß werden, wodurch die genannten Fehler unbedeutend werden.
Wenn Ihr Programm Kinder hervorbringt und diese den Speicher zuweisen, wird es komplexer, und Sie sollten Hilfsskripte schreiben, um Prozesse unter Ihrer Kontrolle auszuführen. Ich habe in meinem Blog geschrieben, warum und wie.
Es gibt einige Probleme mit ulimit. Hier ist eine nützliche Lektüre zum Thema:Zeit- und Speicherverbrauch eines Programms in Linux begrenzen, was zum Timeout-Tool führt, mit dem Sie einen Prozess (und seine Abzweigungen) nach Zeit oder Speicherverbrauch einsperren können.
Das Timeout-Tool erfordert Perl 5+ und den /proc
Dateisystem gemountet. Danach kopiert man das Tool z.B. /usr/local/bin
etwa so:
curl https://raw.githubusercontent.com/pshved/timeout/master/timeout | \
sudo tee /usr/local/bin/timeout && sudo chmod 755 /usr/local/bin/timeout
Danach können Sie Ihren Prozess wie in Ihrer Frage wie folgt durch Speicherverbrauch "einsperren":
timeout -m 500 pdftoppm Sample.pdf
Alternativ können Sie -t <seconds>
verwenden und -x <hertz>
um den Prozess jeweils durch Zeit- oder CPU-Beschränkungen einzuschränken.
Die Funktionsweise dieses Tools besteht darin, mehrmals pro Sekunde zu prüfen, ob der erzeugte Prozess seine festgelegten Grenzen nicht überzeichnet hat. Das bedeutet, dass es tatsächlich ein kleines Fenster gibt, in dem ein Prozess möglicherweise auftreten könnte überzeichnen, bevor eine Zeitüberschreitung bemerkt und den Prozess beendet.
Ein korrekterer Ansatz würde daher wahrscheinlich Cgroups beinhalten, aber das Einrichten ist viel aufwendiger, selbst wenn Sie Docker oder runC verwenden würden, die unter anderem eine benutzerfreundlichere Abstraktion um Cgroups bieten.