ulimit begrenzt nicht die Speichernutzung

7

Wenn ich ein Programm schreibe, kann es vorkommen, dass ein außer Kontrolle geratenes Programm die Hälfte meines Arbeitsspeichers beansprucht (im Allgemeinen aufgrund von praktisch unendlichen Schleifen beim Erstellen großer Datenstrukturen) und das System sehr langsam wird, sodass ich das fehlerhafte Programm nicht einmal töten kann. Deshalb möchte ich ulimit verwenden, um mein Programm automatisch zu beenden, wenn mein Programm abnormal viel Speicher belegt:

$ 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 über ulimit falsch verstanden?

Lüge Ryan
quelle
Wie Sie sehen können, gibt es Einschränkungen für verschiedene Arten von Speicher. Es ist manchmal schwierig, herauszufinden, zu welchen Grenzen eine bestimmte Zuweisungsanzahl gehört. Versuchen Sie, einen "außer Kontrolle geratenen" Prozess zu erstellen und den Inhalt /proc/12345/statusanzugeben, bei dem 12345 die Prozess-ID ist (nur die Zeilen, die mit beginnen, Vmsind ausreichend).
Gilles
@ Gilles: Ich habe versucht, zusätzliche Einschränkungen für "max memory size", "virtual memory", "core file size" und "data seg size" zu setzen. Verwenden Sie nicht viele Dateien. Das Problem beim Sammeln von / proc / besteht darin, dass mein Computer 2-3 Sekunden nach dem Start des Runaway abstürzt und ich mich sehr schwer tun muss, um den störenden Prozess zu beenden (oft würde ich einfach die Energie verbrauchen) Taste). Ich werde versuchen, eine zu erwerben.
Lie Ryan

Antworten:

4

Ihr Beispiel sollte so funktionieren, wie Sie denken (Programm wird beendet, nachdem zu viel RAM verbraucht wurde). Ich habe gerade einen kleinen Test auf meinem Shell-Server durchgeführt:

Zuerst habe ich meine Limits auf WIRKLICH niedrig begrenzt:

ulimit -m 10
ulimit -v 10

Das führte dazu, dass alles getötet wurde. ls, dateund andere kleine Kommandos werden noch vor dem Start abgefeuert.

Welche Linux Distribution benutzt du? Verwendet Ihr Programm nur einen einzigen Prozess oder erzeugt es Tonnen von untergeordneten Prozessen? Im letzteren Fall ist ulimit möglicherweise nicht immer wirksam.

Janne Pikkarainen
quelle
Ich benutze gentoo und mein Programm hat keine Unterprozesse erzeugt, aber es benutzt SDL und OpenGL. Könnte das die Ursache sein? Das Setzen von ulimit auf einen extrem niedrigen Wert führt dazu ls, dass etc und mein Programm getötet werden. Das Programm benötigt bei normaler Verwendung zwischen 4000 und 8000 (bei 4000 wird die SDL-Bibliothek nicht geladen, und bei 8000 wird das Programm nicht beendet, obwohl sich topgezeigt hat, dass es mehr als ein halbes Gigabyte RAM gefressen hat)
Lie Ryan
1

Dies funktioniert nur in einer einzelnen Bash-Sitzung, es sei denn, Sie fügen sie in Ihr .bash_profile ein und gelten nicht für die bereits ausgeführten Prozesse.

Was ich merkwürdig finde ist, dass die:

 max memory size         (kbytes, -m) unlimited

ist in /etc/security/limits.conf nicht vorhanden, obwohl dies nur den Speicherverbrauch pro Prozess begrenzt, nicht insgesamt für 1 Benutzerkonto. Anstatt Cgroup hinzuzufügen, sollten sie nur die vorhandenen Unix-Befehle ändern, um diese neuen Funktionen aufzunehmen.

snoemq
quelle
1
Ich wusste, dass ulimit nur innerhalb derselben Bash-Shell für Programme funktioniert, die nach dem Festlegen des Limits gestartet wurden (siehe, wie ich das Programm aus meiner Beispiel-Shell-Sitzung heraus gestartet habe) .
Lie Ryan