Ich fand, das pidstat
wäre ein gutes Werkzeug, um Prozesse zu überwachen. Ich möchte die durchschnittliche Speichernutzung eines bestimmten Prozesses berechnen. Hier ist ein Beispiel für eine Ausgabe:
02:34:36 PM PID minflt/s majflt/s VSZ RSS %MEM Command
02:34:37 PM 7276 2.00 0.00 349212 210176 7.14 scalpel
(Dies ist Teil der Ausgabe von pidstat -r -p 7276
.)
Soll ich den durchschnittlichen Speicherverbrauch anhand der Informationen zu Resident Set Size (RSS) oder Virtual Size (VSZ) berechnen? Ich habe ein paar Dinge auf Wikipedia und in Foren gelesen, bin mir aber nicht sicher, ob ich die Unterschiede vollständig verstehe. Außerdem scheint keiner von ihnen zuverlässig zu sein. Wie kann ich einen Prozess überwachen, um die Speichernutzung zu ermitteln?
Jede Hilfe in dieser Angelegenheit wäre nützlich.
Antworten:
RSS gibt an, wie viel Speicher dieser Prozess derzeit im Hauptspeicher (RAM) hat. VSZ gibt an, über wie viel virtuellen Speicher der Prozess insgesamt verfügt. Dies schließt alle Arten von Speicher ein, sowohl im RAM als auch ausgelagert. Diese Zahlen können verzerrt werden, da sie auch gemeinsam genutzte Bibliotheken und andere Speichertypen enthalten. Es können 500 Instanzen
bash
ausgeführt werden, und die Gesamtgröße des Speicherbedarfs entspricht nicht der Summe der RSS- oder VSZ-Werte.Wenn Sie eine detailliertere Vorstellung vom Speicherbedarf eines Prozesses erhalten möchten, haben Sie einige Optionen. Sie können durchgehen
/proc/$PID/map
und die Sachen aussortieren, die Sie nicht mögen. Wenn es sich um gemeinsam genutzte Bibliotheken handelt, kann die Berechnung je nach Ihren Anforderungen (an die ich mich zu erinnern glaube) komplex werden.Wenn Sie sich nur um die Größe des Heapspeichers kümmern, können Sie immer nur den
[heap]
Eintrag in dermap
Datei analysieren . Die Größe der Kernel für den Prozess Heap zugewiesen hat , kann oder kann nicht die genaue Anzahl von Bytes reflektieren den Prozess hat gefragt , zugeordnet werden. Es gibt winzige Details, Kernel-Interna und Optimierungen, die dies verhindern können. In einer idealen Welt wird es so viel sein, wie Ihr Prozess benötigt, auf das nächste Vielfache der Systemseitengröße aufgerundet (getconf PAGESIZE
wird Ihnen sagen, was es ist - auf PCs sind es wahrscheinlich 4.096 Bytes).Wenn Sie sehen möchten, wie viel Speicher ein Prozess zugewiesen hat , können Sie am besten auf die kernseitigen Metriken verzichten. Stattdessen instrumentieren Sie die Heapspeicher- (De-) Zuweisungsfunktionen der C-Bibliothek mit dem
LD_PRELOAD
Mechanismus. Persönlich missbrauche ich leichtvalgrind
, um Informationen über solche Dinge zu erhalten. (Beachten Sie, dass zum Anwenden der Instrumentierung ein Neustart des Prozesses erforderlich ist.)Bitte beachten Sie, dass Sie möglicherweise auch Laufzeiten messen, wodurch
valgrind
Ihre Programme etwas langsamer werden (aber wahrscheinlich innerhalb Ihrer Toleranzen).quelle
/proc/$PID/maps
ist es ein Tippfehler oder ein Unterschied in der Distribution?Minimal lauffähiges Beispiel
Damit dies sinnvoll ist, müssen Sie die Grundlagen des Paging verstehen: https://stackoverflow.com/questions/18431261/how-does-x86-paging-work und insbesondere, dass das Betriebssystem virtuellen Speicher über Seitentabellen zuordnen kann / die interne Speicherbuchhaltung (virtueller VSZ-Speicher), bevor tatsächlich ein Backup-Speicher im RAM oder auf der Festplatte (RSS-residenter Speicher) vorhanden ist.
Um dies in Aktion zu beobachten, erstellen wir ein Programm, das:
mmap
Haupt c
GitHub Upstream .
Kompilieren und ausführen:
wo:
echo 1 | sudo tee /proc/sys/vm/overcommit_memory
: Erforderlich, damit Linux einen MMAP-Aufruf ausführen kann, der größer als der physische RAM ist: https://stackoverflow.com/questions/2798330/maximum-memory-which-malloc-can-allocate/57687432#57687432Programmausgabe:
Status beenden:
was nach der 128 + Signalnummer-Regel bedeutet, dass wir eine Signalnummer haben
9
, dieman 7 signal
besagt , dass SIGKILL vom Linux -Killer für nicht genügend Arbeitsspeicher gesendet wird .Ausgangsinterpretation:
printf '0x%X\n' 0x40009A4 KiB ~= 64GiB
(ps
Werte in KiB).extra_memory_committed 0
, was bedeutet, dass wir noch keine Seiten berührt haben. RSS ist ein kleines1648 KiB
Programm, das für den normalen Programmstart wie Textbereiche, Globals usw. vorgesehen ist.8388608 KiB == 8GiB
. Dadurch erhöhte sich RSS um genau 8GIB auf8390256 KiB == 8388608 KiB + 1648 KiB
Siehe auch: Benötigen Sie eine Erklärung zu Resident Set Size / Virtual Size
OOM Killer Logs
Unsere
dmesg
Befehle haben die OOM-Killer-Protokolle angezeigt.Eine genaue Interpretation dieser wurde angefragt bei:
Die allererste Zeile des Protokolls lautete:
Interessanterweise war es der MongoDB-Daemon, der immer auf meinem Laptop im Hintergrund lief, der den OOM-Killer auslöste, vermutlich, als das arme Ding versuchte, Speicher zuzuweisen.
Der OOM-Killer muss jedoch nicht unbedingt denjenigen töten, der ihn aufgeweckt hat.
Nach dem Aufruf druckt der Kernel eine Tabelle oder Prozesse aus, einschließlich
oom_score
:und weiter vorne sehen wir, dass unsere eigene kleine
main.out
tatsächlich bei der vorherigen Anrufung getötet wurde:In diesem Protokoll wird der
score 865
Prozess erwähnt, der vermutlich die höchste (schlechteste) OOM-Killer-Punktzahl aufwies. Wie entscheidet der OOM-Killer, welcher Prozess zuerst beendet wird?Interessanterweise geschah anscheinend alles so schnell, dass bevor der freigegebene Speicher abgerechnet wurde, der
oom
durch denDeadlineMonitor
Vorgang wieder aufgeweckt wurde :und diesmal, dass einige Chromium-Prozess, die in der Regel mein Computer normales Gedächtnisschwein ist getötet:
Getestet in Ubuntu 19.04, Linux-Kernel 5.0.0.
quelle