Wie zu analysieren, golang Speicher?
Schrieb ich eine golang-Programm, das verwendet 1,2 GB Speicher zur Laufzeit.
Aufrufen go tool pprof http://10.10.58.118:8601/debug/pprof/heap
Ergebnisse in einem dump nur mit 323.4 MB heap-Verbrauch.
- Was über den rest der Speichernutzung?
- Gibt es besseres Werkzeug, um zu erklären, golang-runtime-Speicher?
Mit gcvis
ich dieses:
.. und diese heap-form Profil:
Hier ist mein code: https://github.com/sharewind/push-server/blob/v3/broker
- Veröffentlichen Sie Ihren code. Sagen Sie uns, was dein Programm tut.
- Vielleicht, weil ein gc? dave.cheney.net/2014/07/11/visualising-the-go-garbage-collector helfen könnte.
- Es sieht aus wie die verbliebenen Speicher ist nicht garbaged gesammelt und loslassen, um das system. Es ist getan, nach ein paar Minuten der Inaktivität. Warten Sie 8 Minuten und erneut prüfen. Überprüfen Sie diesen link für eine Anleitung, wie zu Debuggen/Profil Gehen Programme: software.intel.com/en-us/blogs/2014/05/10/...
- Siehe auch Laufzeit.MemStats erklärt in golang.org/pkg/runtime/#MemStats
Du musst angemeldet sein, um einen Kommentar abzugeben.
Heap Profil zeigt aktive Arbeitsspeicher der Laufzeitumgebung glaubt, wird von der go-Programm (sprich: noch nicht erhoben wurden, durch den garbage collector). Wenn der GC nicht sammeln-Speicher das Profil verkleinert, aber kein Speicher an das system zurückgegeben. Ihre zukünftige Zuweisungen werden versuchen, die Verwendung von Speicher aus dem pool der bisher gesammelten Objekte, bevor du das system für mehr.
Von außen, das bedeutet, dass Ihr Programm-Speicher verwenden, wird Sie entweder steigen, oder bleiben Ebene. Was die außerhalb der system präsentiert als die "Resident Size" des Programms ist die Anzahl der bytes des RAM zugeordnet ist, zu Ihrem Programm, ob es hält, in-go-Werte, die gesammelt oder lieben.
Der Grund, warum diese beiden zahlen sind oft ganz anders sind da:
Wenn Sie möchten, eine genaue Aufschlüsselung, wie Gehen, sieht der Arbeitsspeicher der Laufzeitumgebung.ReadMemStats nennen: http://golang.org/pkg/runtime/#ReadMemStats
Alternativ, da Sie über eine web-basierte profiling, wenn Sie den Zugriff auf die profiling-Daten durch Ihren browser an:
http://10.10.58.118:8601/debug/pprof/
Klick auf die heap-link erhalten Sie die debugging-Ansicht der heap Profil, die hat einen Ausdruck, der eine Laufzeit.MemStats Struktur an der Unterseite.Die Laufzeit.MemStats Dokumentation (http://golang.org/pkg/runtime/#MemStats) hat die Erklärung aller Felder, aber die interessant sind für diese Diskussion sind:
Wird es immer noch Diskrepanzen zwischen Sys und was das OS meldet das da was Gehen, fragt das system, und was das OS gibt es nicht immer die gleichen. Auch CGO /syscall (zB: malloc /mmap) Speicher wird nicht aufgespürt durch gehen.
/debug/pprof/heap
nicht enthalten ist ein Ausdruck der Laufzeit.MemStats structAlloc
undHeapAlloc
haben die gleiche Bedeutung.Als Ergänzung zu @Cookie Neun die Antwort in Kurzform: man kann versuchen, die
--alloc_space
option.go tool pprof
verwenden--inuse_space
standardmäßig. Es Proben, Speicher-Auslastung, so das Ergebnis ist Teilmenge von den realen.Durch
--alloc_space
pprof gibt alle alloced Speicher, da das Programm begann.--alloc_space
ist genau das, was ich suchte.Ich war immer verwirrt über die wachsende Wohn-Erinnerung an meine Gehe zu Programme, und schließlich musste ich lernen, die profiling-tools, die vorhanden sind, Gehen ökosystems. Runtime bietet viele Metriken innerhalb einer - Laufzeit.Memstats Struktur, aber es kann schwierig sein zu verstehen, welche von Ihnen können helfen, um herauszufinden, die Gründe der Speicher-Wachstum, so werden einige weitere tools benötigt werden.
Profiling-Umgebung
Verwenden https://github.com/tevjef/go-runtime-metrics in Ihrer Anwendung. Zum Beispiel, können Sie dieses in Ihrem
main
:Laufen
InfluxDB
undGrafana
innerhalbDocker
Behälter:Eingerichtet Interaktion zwischen
Grafana
undInfluxDB
Grafana
(Grafana main Seite -> Oben Links -> Datasources -> Add new datasource):Importieren von dashboard - #3242 von https://grafana.com (Grafana main Seite -> Oben Links -> Dashboard -> Importieren):
Schließlich, starten Sie Ihre Anwendung: es wird übertragen-Laufzeit-Metriken, um die contenerized
Influxdb
. Legen Sie Ihre Anwendung unter angemessener Belastung (in meinem Fall war es ziemlich klein - 5 RPS für ein paar Stunden).Speicherverbrauch Analyse
Sys
(das synonim vonRSS
) - Kurve ist sehr ähnlich zuHeapSys
Kurve. Stellt sich heraus, dass die dynamische Speicherverwaltung war der wichtigste Faktor der gesamten Speicher-Wachstum, so dass die kleine Menge an Speicher verbraucht, stack-Variablen scheinen eine Konstante und kann ignoriert werden;HeapIdle
wächst mit der gleichen rate wie einSys
, währendHeapReleased
ist immer null. Offensichtlich runtime nicht zurück-Speicher für OS an alle , zumindest unter den Bedingungen dieses Tests:Für diejenigen, die versuchen, das problem zu untersuchen Speicherverbrauch würde ich empfehlen, Folgen Sie den beschriebenen Schritten, um auszuschließen, einige triviale Fehler (wie goroutine Leck).
Freigeben von Speicher explizit
Es ist interessant, dass die, die können erheblich reduzieren den Speicherverbrauch mit der expliziten Aufrufe
debug.FreeOSMemory()
:In der Tat, dieser Ansatz gespart über 35% der Speicher im Vergleich mit den Standard-Bedingungen.
Können Sie auch StackImpact, die automatisch Aufzeichnungen und Berichte regelmäßig und Anomalie ausgelöst memory allocation profile auf dem Armaturenbrett, die in einem historischen und vergleichbarer form. Dieser blog-post für weitere details Memory-Leak-Detection in Produktion Gehen Anwendungen
Disclaimer: ich arbeite für StackImpact
--alloc_space
, das ist nicht geeignet für memory-leak-detection. Es wird nur zeigen Ihnen, wie viel Speicher zugewiesen wurde seit dem start des Programms. Für einen lange Laufenden Programm können die zahlen ziemlich hoch. Wir sind nicht bewusst alle Speicherlecks in der StackImpact agent so weit.