En tant qu'administrateur système, je suis parfois confronté à des situations où un programme se comporte anormalement, sans créer d'erreurs ou créer des messages d'erreur absurdes.
Dans le passé - avant l'arrivée de Java - il y avait deux contre-mesures:
Si rien d'autre ne vous aide - RTFM ;-)
Si même 1. n'aide pas - tracez les appels système et voyez ce qui se passe
J'utilise habituellement strace -fpour cette tâche avec Linux (d'autres OS ont des outils de trace similaires). Maintenant, alors que cela fonctionne généralement bien pour tout programme à l'ancienne, la trace devient très floue lorsque vous faites la même chose sur un processus java . Il y a tellement d'appels système apparemment sans rapport avec une action réelle, qu'il est terrible de chercher dans un tel vidage.
Y a-t-il de meilleures façons de le faire (si le code source n'est pas disponible)?
Comme l'a mentionné ckhan, jstackc'est génial car il donne la trace complète de la pile de tous les threads actifs dans la JVM. La même chose peut être obtenue sur stderr de la JVM en utilisant SIGQUIT.
Un autre outil utile est celui jmapqui peut récupérer un vidage de tas du processus JVM en utilisant le PID du processus:
jmap -dump:file=/tmp/heap.hprof $PID
Ce vidage de tas peut être chargé dans des outils tels que visualvm(qui fait maintenant partie de l'installation standard d'Oracle Java SDK, nommée jvisualvm). De plus, VisualVM peut se connecter à la JVM en cours d'exécution et afficher des informations sur la JVM, notamment en affichant des graphiques de l'utilisation interne du processeur, du nombre de threads et de l'utilisation du segment de mémoire - idéal pour localiser les fuites.
Un autre outil, jstatpeut collecter des statistiques de récupération de place pour la JVM sur une période similaire à vmstat lorsqu'il est exécuté avec un argument numérique (par exemple vmstat 3).
Enfin, il est possible d'utiliser un agent Java pour pousser l'instrumentation sur toutes les méthodes de tous les objets au moment du chargement. La bibliothèque javassistpeut aider à rendre cela très facile à faire. Il est donc possible d'ajouter votre propre traçage. La partie difficile avec cela serait de trouver un moyen d'obtenir une sortie de trace uniquement lorsque vous le souhaitez et pas tout le temps, ce qui ralentirait probablement la JVM à une analyse. Il y a un programme appelé dtracequi fonctionne d'une manière comme celle-ci. Je l'ai essayé, mais je n'ai pas eu beaucoup de succès. Notez que les agents ne peuvent pas instrumenter toutes les classes car celles nécessaires pour amorcer la JVM sont chargées avant que l'agent puisse instrumenter, puis il est trop tard pour ajouter une instrumentation à ces classes.
Ma suggestion - commencez par VisualVM et voyez si cela vous dit ce que vous devez savoir car il peut afficher les threads actuels et les statistiques importantes pour la JVM.
Au fait, c'est une question géniale; J'espère que plus de gens ajouteront des réponses avec d'autres idées. Quand j'ai demandé aux gens qui travaillent avec Java depuis de nombreuses années de tracer, ils m'ont donné des regards vides. Peut-être qu'ils ne connaissent tout simplement pas la beauté de la strace.
ash
10
De la même manière, lors du débogage de programmes qui ont mal tourné sur un système Linux, vous pouvez utiliser des outils similaires pour déboguer les JVM en cours d'exécution sur votre système.
Outil n ° 1 - jvmtop
De manière similaire à top, vous pouvez utiliser jvmtop pour voir quelles classes sont disponibles dans les JVM en cours d'exécution sur votre système. Une fois installé, vous l'invoquez comme ceci:
$ jvmtop.sh
Sa sortie est de style similaire pour ressembler à l'outil top:
JvmTop 0.8.0 alpha amd64 8 cpus, Linux 2.6.32-27, load avg 0.12
http://code.google.com/p/jvmtop
PID MAIN-CLASS HPCUR HPMAX NHCUR NHMAX CPU GC VM USERNAME #T DL
3370 rapperSimpleApp 165m 455m 109m 176m 0.12% 0.00% S6U37 web 21
11272 ver.resin.Resin [ERROR: Could not attach to VM]
27338 WatchdogManager 11m 28m 23m 130m 0.00% 0.00% S6U37 web 31
19187 m.jvmtop.JvmTop 20m 3544m 13m 130m 0.93% 0.47% S6U37 web 20
16733 artup.Bootstrap 159m 455m 166m 304m 0.12% 0.00% S6U37 web 46
Outil n ° 2 - jvmmonitor
Une autre alternative consiste à utiliser jvmmonitor . JVM Monitor est un profileur Java intégré à Eclipse pour surveiller le CPU, les threads et l'utilisation de la mémoire des applications Java. Vous pouvez soit l'utiliser pour rechercher automatiquement les JVM en cours d'exécution sur l'hôte local, soit vous connecter à des JVM distantes à l'aide d'un port @ host.
Outil n ° 3 - VisualVM
visualvm est probablement "l'outil" à atteindre lors du débogage de problèmes avec la JVM. Son ensemble de fonctionnalités est assez profond et vous pouvez obtenir un aperçu très approfondi des entrailles.
Profil des performances des applications ou analyse de l'allocation de mémoire:
Considérez jstack. Pas tout à fait un match pour strace, plus d'un pstack-analog, mais vous donnera au moins une image d'un instantané dans le temps. Pourrait les enchaîner pour obtenir une trace brute si vous deviez.
Si vous utilisez RHEL OpenJDK (ou similaire, le fait est que ce n'est pas le JDK d'Oracle), vous pouvez utiliser SystemTap pour cela.
Certaines sondes sont activées en utilisant les options de ligne de commande java -XX:+DTraceMethodProbes, -XX:+DTraceAllocProbes, -XX:+DTraceMonitorProbes. Notez que l'activation de ces sondes affectera considérablement les performances du programme.
Vous pouvez également utiliser jstack()pour obtenir la pile Java du processus, mais cela ne fonctionnera que si vous démarrez SystemTap avant JVM.
Notez que SystemTap tracera chaque méthode. Il n'est également pas en mesure d'obtenir les arguments de la méthode. Une autre option consiste à utiliser les propres capacités de traçage de la JVM, appelées JVMTI. L' un des plus célèbres implémentations JVMTI est BTrace .
Il est conseillé d'essayer Jackplay , qui est un outil de traçage JVM vous permettant de suivre l'entrée et la sortie de la méthode sans changement de code ou redéploiement.
De la même manière, lors du débogage de programmes qui ont mal tourné sur un système Linux, vous pouvez utiliser des outils similaires pour déboguer les JVM en cours d'exécution sur votre système.
Outil n ° 1 - jvmtop
De manière similaire à
top
, vous pouvez utiliser jvmtop pour voir quelles classes sont disponibles dans les JVM en cours d'exécution sur votre système. Une fois installé, vous l'invoquez comme ceci:Sa sortie est de style similaire pour ressembler à l'outil
top
:Outil n ° 2 - jvmmonitor
Une autre alternative consiste à utiliser jvmmonitor . JVM Monitor est un profileur Java intégré à Eclipse pour surveiller le CPU, les threads et l'utilisation de la mémoire des applications Java. Vous pouvez soit l'utiliser pour rechercher automatiquement les JVM en cours d'exécution sur l'hôte local, soit vous connecter à des JVM distantes à l'aide d'un port @ host.
Outil n ° 3 - VisualVM
visualvm est probablement "l'outil" à atteindre lors du débogage de problèmes avec la JVM. Son ensemble de fonctionnalités est assez profond et vous pouvez obtenir un aperçu très approfondi des entrailles.
Profil des performances des applications ou analyse de l'allocation de mémoire:
Prendre et afficher les vidages de threads:
Les références
la source
Considérez
jstack
. Pas tout à fait un match pourstrace
, plus d'unpstack
-analog, mais vous donnera au moins une image d'un instantané dans le temps. Pourrait les enchaîner pour obtenir une trace brute si vous deviez.Voir également les suggestions de cet article SO: /programming/1025681/call-trace-in-java
la source
Si vous utilisez RHEL OpenJDK (ou similaire, le fait est que ce n'est pas le JDK d'Oracle), vous pouvez utiliser SystemTap pour cela.
Certaines sondes sont activées en utilisant les options de ligne de commande java
-XX:+DTraceMethodProbes
,-XX:+DTraceAllocProbes
,-XX:+DTraceMonitorProbes
. Notez que l'activation de ces sondes affectera considérablement les performances du programme.Voici un exemple de script SystemTap:
Vous pouvez également utiliser
jstack()
pour obtenir la pile Java du processus, mais cela ne fonctionnera que si vous démarrez SystemTap avant JVM.Notez que SystemTap tracera chaque méthode. Il n'est également pas en mesure d'obtenir les arguments de la méthode. Une autre option consiste à utiliser les propres capacités de traçage de la JVM, appelées JVMTI. L' un des plus célèbres implémentations JVMTI est BTrace .
la source
Il est conseillé d'essayer Jackplay , qui est un outil de traçage JVM vous permettant de suivre l'entrée et la sortie de la méthode sans changement de code ou redéploiement.
la source