Comment analyser golang de la mémoire?
J'ai écrit un golang programme, qui utilise 1.2 GO de mémoire lors de l'exécution.
Appel go tool pprof http://10.10.58.118:8601/debug/pprof/heap
résultats dans une décharge avec seulement 323.4 MO utilisation du tas.
- Le reste de l'utilisation de la mémoire?
- Est-il meilleur outil pour expliquer golang de la mémoire d'exécution?
À l'aide de gcvis
j'obtiens ceci:
.. et ce tas de forme profil:
Voici mon code: https://github.com/sharewind/push-server/blob/v3/broker
- Poster votre code. Dites-nous ce que votre programme n'.
- Peut-être parce que d'un gc? dave.cheney.net/2014/07/11/visualising-the-go-garbage-collector pourrait aider.
- Il ressemble à la remaning la mémoire n'est pas garbaged recueillies et relâchez-le pour le système. Il est fait après quelques minutes d'inactivité. Attendre 8 minutes et vérifiez de nouveau. Suivez ce lien pour un guide de comment déboguer/profil de programmes: software.intel.com/en-us/blogs/2014/05/10/...
- Voir aussi l'exécution.MemStats expliqué dans golang.org/pkg/runtime/#MemStats
Vous devez vous connecter pour publier un commentaire.
Le tas de profil montre active de la mémoire, de la mémoire à l'exécution croit est en cours d'utilisation par le programme de go (c'est à dire: n'a pas été recueillies par le garbage collector). Lorsque le GC ne se recueillir à la mémoire que le profil se rétrécit, mais pas de mémoire est renvoyé dans le système. Votre les allocations futures essayez d'utiliser la mémoire de la piscine de déjà recueilli des objets avant de demander au système pour plus d'.
De l'extérieur, cela signifie que votre programme est l'utilisation de la mémoire seront en augmentation, ou de rester au niveau. Ce que le système se présente comme le "Résident" Taille de votre programme est le nombre d'octets de RAM est attribué à votre programme si elle tient à usage allez valeurs ou celles recueillies.
La raison pour laquelle ces deux nombres sont souvent très différents, parce que:
Si vous voulez une répartition précise de comment Aller voit le mémoire que vous pouvez utiliser le moteur d'exécution.ReadMemStats appel: http://golang.org/pkg/runtime/#ReadMemStats
Sinon, puisque vous êtes à l'aide de web basé sur le profilage si vous pouvez accéder au profilage de données par le biais de votre navigateur à:
http://10.10.58.118:8601/debug/pprof/
, en cliquant sur le tas de lien vous montrera le débogage de vue du tas de profil, qui a une impression d'une exécution.MemStats structure au fond.Le moment de l'exécution.MemStats documentation (http://golang.org/pkg/runtime/#MemStats) a l'explication de tous les champs, mais ce qui est intéressant pour cette discussion sont les suivants:
Il y aura toujours des divergences entre les Sys, et que les OS des rapports parce que ce qui va demande du système, et ce que l'OS lui donne ne sont pas toujours les mêmes. Aussi CGO /syscall (par exemple: malloc /mmap) de la mémoire n'est pas suivi par aller.
/debug/pprof/heap
ne contient pas une copie de l'exécution.MemStats structAlloc
etHeapAlloc
ont le même sens.Comme un complément à @Cookie de Neuf réponse, en bref: vous pouvez essayer le
--alloc_space
option.go tool pprof
utilisation--inuse_space
par défaut. Il échantillons de l'utilisation de la mémoire de sorte que le résultat est sous-ensemble de réel.Par
--alloc_space
pprof renvoie tous les alloced mémoire depuis que le programme a commencé.--alloc_space
est exactement ce que je cherchais.J'ai toujours été confus au sujet de la croissance résidentielle de la mémoire de mon Go applications, et enfin, j'ai eu à apprendre les outils de profilage qui sont présents dans Aller de l'écosystème. Runtime fournit de nombreuses mesures en une moment de l'exécution.Memstats structure, mais il peut être difficile à comprendre lequel d'entre eux peut vous aider à trouver les raisons de la croissance de la mémoire, de sorte que certains des outils supplémentaires sont nécessaires.
De profilage de l'environnement
Utilisation https://github.com/tevjef/go-runtime-metrics dans votre application. Par exemple, vous pouvez mettre ceci dans votre
main
:Exécuter
InfluxDB
etGrafana
dansDocker
conteneurs:Ensemble de l'interaction entre des
Grafana
etInfluxDB
Grafana
(Grafana page principale -> en Haut à gauche -> Sources de données -> Ajouter une nouvelle source de données):Importation de tableau de bord #3242 de https://grafana.com (Grafana page principale -> en Haut à gauche -> tableau de bord -> Import):
Enfin, le lancement de votre application: il transmettra exécution des métriques de la contenerized
Influxdb
. Mettre votre application en vertu de l'raisonnable de la charge (dans mon cas c'était assez petite de 5 RPS pour une à plusieurs heures).Mémoire analyse de la consommation d'
Sys
(le synonim deRSS
) de la courbe est assez similaire àHeapSys
courbe. S'avère que l'allocation dynamique de la mémoire a été le principal facteur de la croissance globale de la mémoire, de sorte que la petite quantité de mémoire consommée par pile variables semblent être constante et peut être ignoré;HeapIdle
est croissante avec le même taux que l'Sys
, tandis queHeapReleased
est toujours à zéro. Évidemment runtime ne revient pas en mémoire d'OS à tous les , au moins dans les conditions de ce test:Pour ceux qui cherche à étudier le problème de la consommation de mémoire je vous recommande de suivre les étapes dans l'ordre pour exclure certaines erreurs triviales (comme goroutine de fuite).
La libération de la mémoire explicite
Il est intéressant de noter que l'on peut réduire considérablement la consommation de mémoire avec des appels explicites à
debug.FreeOSMemory()
:En fait, cette approche a sauvé environ 35% de mémoire en comparaison avec les conditions par défaut.
Vous pouvez également utiliser StackImpact, qui enregistre automatiquement et de rapports réguliers et anomalie déclenchée par l'allocation de la mémoire des profils pour le tableau de bord, qui sont disponibles dans un historique et comparables forme. Voir ce billet de blog pour plus de détails Détection Fuite de mémoire dans l'environnement de Production des Applications
Disclaimer: je travaille pour StackImpact
--alloc_space
, ce qui n'est pas adapté pour la mémoire de détection de fuite. Il va juste vous montrer combien de mémoire a été allouée depuis le début du programme. Pour un long programme de course, les chiffres peuvent être assez élevée. Nous ne connaissons pas de fuites de mémoire dans le StackImpact de l'agent jusqu'à présent.