
Beim Schreiben von Programmen kommt es vor, dass ein außer Kontrolle geratenes Programm die Hälfte meines RAM verschlingt (normalerweise aufgrund praktisch unendlicher Schleifen beim Erstellen großer Datenstrukturen) und das System so langsam wird, dass ich das fehlerhafte Programm nicht einmal beenden kann. Daher möchte ich ulimit verwenden, um mein Programm automatisch zu beenden, wenn es eine ungewöhnlich große Menge an Speicher verwendet:
$ ulimit -a
core file size (blocks, -c) 1000
data seg size (kbytes, -d) 10000
scheduling priority (-e) 0
file size (blocks, -f) 1000
pending signals (-i) 6985
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) 10000
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 6985
virtual memory (kbytes, -v) 100000
file locks (-x) unlimited
$ ./run_program
aber warum verwendet mein Programm immer noch mehr RAM als das angegebene Limit (ja, ich starte das Programm in derselben Bash-Shell)?
Habe ich etwas bezüglich ulimit falsch verstanden?
Antwort1
Ihr Beispiel sollte wie erwartet funktionieren (das Programm wird beendet, wenn zu viel RAM verbraucht wird). Ich habe gerade einen kleinen Test auf meinem Shell-Server durchgeführt:
Zuerst habe ich meine Limits WIRKLICH niedrig gesetzt:
ulimit -m 10
ulimit -v 10
Das führte dazu, dass so ziemlich alles getötet wurde, ls
und date
andere kleine Kommandos wurden abgeschossen, bevor sie überhaupt begannen.
Welche Linux-Distribution verwenden Sie? Verwendet Ihr Programm nur einen einzigen Prozess oder erzeugt es Unmengen von untergeordneten Prozessen? Im letzteren Fall ist ulimit möglicherweise nicht immer effektiv.
Antwort2
ulimit -m
funktioniert nicht mehr. Verwenden Sie ulimit -v
stattdessen.
Der Grund dafür ist, dass ulimit
Aufrufe setrlimit undMann setrlimitsagt:
RLIMIT_RSS Gibt die Grenze (in Bytes) des Resident Set des Prozesses an (die Anzahl der virtuellen Seiten, die im RAM resident sind). Diese Grenze hat nur unter Linux 2.4.x, x < 30, Auswirkungen und betrifft dort nur Aufrufe von madvise(2), die MADV_WILLNEED angeben.
Antwort3
Dies funktioniert nur in einer einzelnen Bash-Sitzung, es sei denn, Sie fügen es in Ihr .bash_profile ein und gilt nicht für die bereits laufenden Prozesse.
Was ich seltsam finde, ist, dass:
max memory size (kbytes, -m) unlimited
ist in /etc/security/limits.conf nicht vorhanden, obwohl es nur den Speicherverbrauch pro Prozess begrenzt, nicht insgesamt für ein Benutzerkonto. Anstatt Cgroup hinzuzufügen, hätten sie einfach die vorhandenen Unix-Befehle ändern sollen, um diese neuen Funktionen zu berücksichtigen.