101 votes

Outil pour analyser de gros vidages de la mémoire Java

J'ai un vidage de la mémoire heap JVM HotSpot que je voudrais analyser. La machine virtuelle tournait avec -Xmx31g, et le fichier de vidage de la mémoire heap fait 48 Go.

  • Je n'essaierai même pas jhat, car cela nécessite environ cinq fois la mémoire heap (soit 240 Go dans mon cas) et c'est terriblement lent.
  • Eclipse MAT plante avec une ArrayIndexOutOfBoundsException après avoir analysé le vidage de la mémoire heap pendant plusieurs heures.

Quels autres outils sont disponibles pour cette tâche? Une suite d'outils en ligne de commande serait la meilleure solution, comprenant un programme qui transforme le vidage de la mémoire heap en structures de données efficaces pour l'analyse, combiné avec plusieurs autres outils qui travaillent sur les données pré-structurées.

103voto

Franz See Points 840

Normalement, ce que j'utilise est ParseHeapDump.sh inclus dans Eclipse Memory Analyzer et décrit ici, et je le fais sur l'un de nos serveurs plus puissants (téléchargez et copiez le dossier .zip linux, décompressez là-bas). Le script shell nécessite moins de ressources que l'analyse de la mémoire à partir de l'interface graphique, plus vous pouvez l'exécuter sur votre serveur musclé avec plus de ressources (vous pouvez allouer plus de ressources en ajoutant quelque chose comme -vmargs -Xmx40g -XX:-UseGCOverheadLimit à la fin de la dernière ligne du script. Par exemple, la dernière ligne de ce fichier pourrait ressembler à ceci après la modification

./MemoryAnalyzer -consolelog -application org.eclipse.mat.api.parse "$@" -vmargs -Xmx40g -XX:-UseGCOverheadLimit

Exécutez-le comme ./chemin/vers/ParseHeapDump.sh ../today_heap_dump/jvm.hprof

Après cela réussit, il crée un certain nombre de fichiers "index" à côté du fichier .hprof.

Après avoir créé les index, j'essaie de générer des rapports à partir de cela et de les copier sur mes machines locales pour voir si je peux trouver le coupable juste avec cela (pas seulement les rapports, pas les index). Voici un tutoriel sur la création des rapports.

Rapport d'exemple :

./ParseHeapDump.sh ../today_heap_dump/jvm.hprof org.eclipse.mat.api:suspects

Autres options de rapport :

org.eclipse.mat.api:overview et org.eclipse.mat.api:top_components

Si ces rapports ne sont pas suffisants et si j'ai besoin de creuser plus (par exemple via oql), je transfère les index ainsi que le fichier hprof sur ma machine locale, puis j'ouvre le fichier de heap dump (avec les index dans le même répertoire que le fichier de heap dump) avec mon interface graphique Eclipse MAT. À partir de là, il n'a pas besoin de beaucoup de mémoire pour s'exécuter.

EDIT : Je voulais juste ajouter deux notes :

  • D'après ce que je sais, seule la génération des index est la partie intensive en mémoire d'Eclipse MAT. Après avoir les index, la plupart de vos traitements avec Eclipse MAT n'auraient pas besoin de autant de mémoire.
  • Le faire dans un script shell signifie que je peux le faire sur un serveur sans tête (et je le fais normalement sur un serveur sans tête également, car ce sont généralement les plus puissants). Et si vous avez un serveur qui peut générer un fichier de heap dump de cette taille, il est probable que vous ayez un autre serveur qui peut également traiter autant de heap dump.

8voto

Michael Shvets Points 51

Première étape: augmentez la quantité de RAM que vous allouez à MAT. Par défaut, ce n'est pas beaucoup et il ne peut pas ouvrir de gros fichiers.

En cas d'utilisation de MAT sur MAC (OSX), vous aurez un fichier MemoryAnalyzer.ini dans MemoryAnalyzer.app/Contents/MacOS. Pour moi, cela ne fonctionnait pas de faire des ajustements à ce fichier et de les "prendre". Vous pouvez plutôt créer une commande de démarrage modifiée/script shell basée sur le contenu de ce fichier et l'exécuter à partir de ce répertoire. Dans mon cas, je voulais 20 Go de tas :

./MemoryAnalyzer -vmargs -Xmx20g --XX:-UseGCOverheadLimit ... autres paramètres souhaités

Exécutez simplement cette commande/script à partir du répertoire Contents/MacOS via le terminal, pour démarrer l'interface graphique avec plus de RAM disponible.

6voto

Mikaveli Points 3235

La réponse acceptée à cette question connexe devrait vous donner un bon point de départ (si vous avez accès au processus en cours, génère des histogrammes jmap en direct au lieu de des vidages de mémoire, c'est très rapide) :

Méthode pour trouver une fuite de mémoire dans de grands vidages de mémoire Java

La plupart des autres analyseurs de tas (j'utilise IBM http://www.alphaworks.ibm.com/tech/heapanalyzer) nécessitent au moins un pourcentage de RAM supérieur à celui du tas si vous attendez un bel outil GUI.

À part cela, de nombreux développeurs utilisent des approches alternatives, comme l'analyse en direct de la pile pour avoir une idée de ce qui se passe.

Bien que je doive me demander pourquoi vos tas sont si grands ? L'effet sur l'allocation et la collecte des déchets doit être énorme. Je parie qu'un grand pourcentage de ce qui se trouve dans votre tas devrait en fait être stocké dans une base de données / une cache persistante, etc.

6voto

Peter Lawrey Points 229686

Je suggère d'essayer YourKit. Il a généralement besoin de un peu moins de mémoire que la taille du heap dump (il l'indexe et utilise ces informations pour retrouver ce que vous voulez)

5voto

rogerdpack Points 12806

Cette personne http://blog.ragozin.info/2015/02/programatic-heapdump-analysis.html

a écrit un "analyseur de mémoire heap" personnalisé qui expose simplement une interface "style de requête" à travers le fichier de vidage de mémoire, au lieu de charger réellement le fichier en mémoire.

https://github.com/aragozin/heaplib

Je ne sais pas si le "langage de requête" est meilleur que l'OQL eclipse mentionné dans la réponse acceptée ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X