Ich entwickle ein Programm in go; Gelegentlich werden sehr große Speichermengen zugewiesen (>> 10 GB auf einem Computer mit 8 GB physischem Speicher), wodurch das System nicht mehr reagiert. Ich möchte die Menge an Speicher begrenzen, die der Prozess zuweisen kann. Die übliche Art, wie ich das machen würde, ist:
ulimit -m 4000000 ; ./myprogram
... was mein Programm beenden sollte, wenn es versucht, mehr als 4 GB Speicher zu verwenden.
Unter OS X El Capitan scheint dies keine Auswirkungen zu haben. Selbst ulimit -m 1
(Beschränkung aller Programme auf nur 1 KB Speicher!) ist unwirksam.
Wie kann ich eine Obergrenze für den für einen bestimmten Prozess verfügbaren Speicher festlegen?
macos
el-capitan
command-line
memory
development
cpcallen
quelle
quelle
ulimit -m
stelle fest, dass ich gerade festgestellt habe, dass es unter Linux nicht mehr funktioniert (> 2.4.30),ulimit -v
aber immer noch wie erwartet funktioniert. (Wieulimit -m
,ulimit -v
scheint auch keine Auswirkung auf OS X zu haben.)Antworten:
Es gibt zwei Ansätze, um die Speichernutzung einzuschränken: Ex post facto und präventiv. Das heißt, Sie können versuchen, Ihr Programm zu beenden, nachdem es zu groß geworden ist, oder Sie können es so programmieren, dass es überhaupt nicht zu groß wird.
Wenn Sie auf dem Ex-post-Facto-Ansatz bestehen, können Sie das folgende Bash-Skript verwenden. Dieses Skript ermittelt zuerst die Speichermenge (wie durch "resident set size" definiert), die der Prozess mit processid pid verwendet, filtert alle nicht numerischen Daten mit grep heraus und speichert die Menge als Variable n. Das Skript prüft dann, ob n größer als das angegebene x ist. Wenn dies der Fall ist, wird der Prozess mit processid pid abgebrochen.
Bitte beachten Sie:
<pid>
die Prozess-ID Ihres Programms ersetzen .<x>
rss = "resident set size" (dh die tatsächliche Speichergröße) ersetzen, die das Programm nicht überschreiten soll.n=$(ps -<pid> -o rss | grep '[0-9]') if [ $n -gt <x> ]; then kill -9 <pid>; fi
Wenn Sie möchten, dass dies alle y Sekunden ausgeführt wird, schließen Sie es einfach in eine Schleife ein und weisen Sie es an, nach jeder Iteration y Sekunden zu warten. Sie können auch einen ähnlichen Befehl mit schreiben
top
. Ihr Ausgangspunkt wäretop -l 1|grep "<pid>"|awk '{print $10}'
.Die Antwort von @ kenorb hat mir bei meinem Skript geholfen
Während ich glaube, dass dies die Frage beantwortet, glaube ich, dass es auf lange Sicht besser ist, einen präventiven Ansatz mit manueller Speicherzuweisung zu wählen.
Sind Sie sicher, dass die Speichernutzung wirklich ein Problem ist? In der Go- Dokumentation heißt es:
Wenn Sie immer noch glauben, dass Sie ein Problem haben, empfehle ich Ihnen, Ihren Speicher manuell zu verwalten, wie dies in der Programmiersprache C erfolgt. Da go in C geschrieben ist, habe ich vermutet, dass es Möglichkeiten gibt, in die C-Speicherverwaltung / -zuordnungen zu gelangen, und tatsächlich gibt es diese. Sehen Sie sich dieses Github- Repository an, das
Der Anwendungsfall lautet wie folgt:
Dies scheint eine bessere langfristige Lösung zu sein.
Wenn Sie mehr über C erfahren möchten (einschließlich Speicherverwaltung), ist die Programmiersprache C die Standardreferenz.
quelle