web-dev-qa-db-fra.com

Outil d'analyse de grands dumps Java

J'ai un fichier de vidage de tas JVM HotSpot que je souhaiterais analyser. VM fonctionnait avec -Xmx31g et le fichier de vidage de segment de mémoire avait une taille de 48 Go.

  • Je n'essaierai même pas jhat, car il nécessite environ cinq fois plus de mémoire vive (ce qui représente 240 Go dans mon cas) et est extrêmement lent.
  • Eclipse MAT se bloque avec une ArrayIndexOutOfBoundsException après avoir analysé le vidage de segment de mémoire pendant plusieurs heures.

Quels autres outils sont disponibles pour cette tâche? Une suite d’outils de ligne de commande serait préférable; elle consiste en un programme qui transforme le vidage de tas en structures de données efficaces pour l’analyse, associée à plusieurs autres outils fonctionnant avec les données pré-structurées.

65
Roland Illig

Normalement, ce que j'utilise, c'est ParseHeapDump.sh inclus dans Eclipse Memory Analyzer et décrit ici , et je le fais sur un de nos serveurs plus performants (téléchargez et copiez sur la distribution Linux .Zip.) Le script shell nécessite moins de ressources que l'analyse du segment de l'interface graphique. Vous pouvez également l'exécuter sur votre serveur lourd 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 peut ressembler à ceci après modification

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

Exécutez-le comme ./path/to/ParseHeapDump.sh ../today_heap_dump/jvm.hprof

Une fois que 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 envoyer à mes machines locales, puis de voir si je peux trouver le coupable grâce à cela (pas seulement les rapports, pas les index). Voici un tutoriel sur la création des rapports .

Exemple de rapport:

./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 suffisent pas et si j’ai besoin de creuser davantage (c’est-à-dire via oql), j’envoie les index ainsi que le fichier hprof sur ma machine locale, puis j’ouvre le dump de pile (avec les index dans le même répertoire que tas hump) avec mon interface graphique Eclipse MAT. À partir de là, il n’a pas besoin de trop de mémoire pour fonctionner.

EDIT: J'ai simplement aimé ajouter deux notes:

  • Autant que je sache, seule la génération des index constitue la partie mémoire d’Eclipse MAT qui utilise beaucoup de mémoire. Une fois que vous avez les index, la plupart de vos traitements à partir d’Eclipse MAT n’auraient pas besoin de autant de mémoire. 
  • Faire cela sur un script Shell signifie que je peux le faire sur un serveur sans tête (et je le fais normalement aussi sur un serveur sans tête, car ce sont normalement les plus puissants). Et si vous avez un serveur capable de générer un vidage de tas de cette taille, il y a de fortes chances que vous disposiez d'un autre serveur capable de traiter aussi bien un vidage de tas.
55
Franz See

La réponse acceptée à cette question devrait vous donner un bon départ (utilise des histogrammes jmap en direct au lieu des copies de tas):

Méthode de recherche de fuite de mémoire dans de grands dumps 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 de plus que le tas si vous attendez un test de Nice. Outil d'interface graphique.

En dehors de cela, de nombreux développeurs utilisent des approches alternatives, telles que l'analyse live stack, pour avoir une idée de ce qui se passe.

Bien que je dois me demander pourquoi vos tas sont si gros? L'effet sur l'allocation et le ramassage des ordures doit être énorme. Je parierais qu'un pourcentage élevé de ce qu'il y a dans votre tas devrait en réalité être stocké dans une base de données/un cache persistant, etc.

5
Michael

Quelques autres options: 

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

a écrit un analyseur de tas Netbeans personnalisé qui expose simplement une interface de "style de requête" via le fichier de vidage de tas, au lieu de charger le fichier en mémoire.

https://github.com/aragozin/jvm-tools/tree/master/hprof-heap

Bien que je ne sache pas si "son langage d'interrogation" est supérieur à l'Eclipse OQL mentionné dans la réponse acceptée ici.

JProfiler 8.1 (499 USD pour une licence utilisateur) est également said pour pouvoir parcourir de grands tas sans utiliser beaucoup d’argent.

4
rogerdpack

Je suggère d'essayer YourKit. Il nécessite généralement un peu moins de mémoire que la taille du tas (il l’indexe et utilise cette information pour récupérer ce que vous voulez)

3
Peter Lawrey

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.

Si vous utilisez MAT sur MAC (OSX), vous aurez le fichier MemoryAnalyzer.ini dans MemoryAnalyzer.app/Contents/MacOS. Cela ne fonctionnait pas pour moi d'apporter des ajustements à ce fichier et de les faire "prendre". Vous pouvez plutôt créer un script de commande/commande de démarrage modifié en fonction du 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 ... other params desired

Il suffit d’exécuter cette commande/script à partir du répertoire Contents/MacOS via un terminal, pour démarrer l’interface graphique avec plus de RAM disponibles.

3
Michael Shvets

Un outil peu connu - http://dr-brenschede.de/bheapsampler/ fonctionne bien pour les gros tas. Cela fonctionne par échantillonnage, de sorte qu'il ne soit pas obligé de lire le texte en entier, bien qu'un peu capricieux.

2
Ashwin Jayaprakash

Essayez d’utiliser jprofiler, cela fonctionne bien pour l’analyse de grands fichiers .hprof, j’ai essayé avec un fichier d’environ 22 GB.

https://www.ej-technologies.com/products/jprofiler/overview.html
0
Selvam M

Je suis tombé sur un outil intéressant appelé JXray. Il fournit une licence d'essai d'évaluation limitée. Il est très utile de trouver des fuites de mémoire. Vous pouvez essayer.

0
Sankar Natarajan

Ce n'est pas une solution en ligne de commande, mais j'aime bien les outils:

Copiez le tas de vidage sur un serveur assez grand pour l'héberger. Il est très possible que le serveur d'origine puisse être utilisé.

Entrez le serveur via ssh -X pour exécuter l'outil graphique à distance et utilisez jvisualvm du répertoire binaire Java pour charger le fichier .hprof du vidage de segment de mémoire.

L'outil ne charge pas le dump de mémoire complet en une fois, mais charge les pièces lorsqu'elles sont requises. Bien entendu, si vous regardez suffisamment dans le fichier, la mémoire requise atteindra finalement la taille du vidage de tas.

0
kap