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.
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.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.
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:
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.
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.
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)
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.
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.
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
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.
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.