Monitorer une JVM avec Visual VM

Visual VM est un outil de monitoring de JVM locale ou distante. Il est intégré au JDK depuis la version 6 update 7.

Vous le trouverez dans le répertoire JAVA_HOME/bin/jvisualvm.

Il permet notamment de :

- de connaître l'occupation CPU, la taille de la heap, le nombre de threads ainsi que le nombre de classes chargées de la JVM. On peut suivre l'évolution dans le temps de ces métriques.

- de réaliser un dump des threads en activité, de la heap.

Pour monitorer une JVM locale, il suffit de lancer l'outil qui détectera les JVM en cours d'éxécution.

Pour monitorer une JVM distante, il faut au préalable démarrer celle-ci avec les options -Dcom.sun.management.jmxremote (ex pour une plateforme de dev : java -Dcom.sun.management.jmxremote.port=12300 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false ....). Ensuite, il faut connecter Visual VM à la machine distante sur le bon port (12300 dans mon précédent exemple).

Visual VM est un précieux outil pour partir à la recherche d'une fuite mémoire par exemple. On peut lui adjoindre des plugins comme VisualGC qui permet de monitorer le Garbage Collector. Malheureusement, il ne propose pas d'édition de rapport pour le moment.

exemple de monitoring visuel d'une JVM

exemple de monitoring visuel d'une JVM

Pour plus de détails, je vous invite à consulter les sites :

https://visualvm.dev.java.net/

http://java.sun.com/javase/6/docs/technotes/guides/visualvm/index.html

10 commentaires

  1. ça ressemble beaucoup à jconsole qui est déjà présent sur la jdk 5 –> JAVA_HOME/bin/jconsole

    Il fonctionne avec les mêmes paramètres 🙂

  2. VisualVM est présenté comme un outil fédérant tous les outils de monitoring présents dans la JDK : JConsole, jstat, jinfo, jstack, and jmap.
    On peut le considérer comme un JConsole amélioré.

  3. A titre d’information, il est normal que les paramètres soient les mêmes, car dans les deux cas la collecte des informations est faite via jmx et les mbeans.

    Pour ma part, j’ai essayé les deux outils: jconsole et visualvm. Outre l’aspect purement cosmétique de l’interface, ma préférence va à visualvm. Il est pour moi plus intéressant car il dispose de quelques plugins intéressant: notamment TDA (Thread Dump Analyzer), Visual GC Plugin pour voir graphiquement l’évolution du GC en temps réel et Sampler.

    cf. : https://visualvm.dev.java.net/plugins.html

    Visualvm permet avec les plugins de prendre des snapshots de la mémoire (avec le graphe de tout les objets) ce qui ne semble pas être possible via la jconsole.

    On a aussi comme dans jconsole, la visualisation de des threads. Par contre dans les deux cas il n’est pas toujours évident de trouver le thread spécifique que l’on veut monitorer. Si je me rappelle visualvm fournit un graphe de l’activité de chaque Thread dans chaque état (TIMED_WAITING, WAITING, RUNNABLE, etc.)…

    De plus visualvm dispose d’un plugin pour utiliser la jconsole (si c’est pas formidable ça!)

    En résumé j’ai l’impression que la jconsole de base est plus pauvre en fonctionnalités que peut l’être visualvm.

    Sinon dans les deux cas j’ai aimé la possibilité de pouvoir créer ces propres MBeans et les interroger via l’interface.

  4. As-tu déjà essayé d’utiliser VisualGC ou faire un snapshot de la heap sur une JVM distante? VisualVM m’indique que ces fonctionnalités ne sont pas supportées par la JVM distante. Je ne comprends pas pourquoi?

    Sinon j’ajouterai que VisualVM peut également ouvrir et présenter l’état de la mémoire à partir d’un fichier snapshot généré par jmap.

  5. Après test, il semblerait que l’on puisse faire des snapshot de la mémoire sur une application distance, mais pas utiliser Visual GC… 🙁

  6. Une autre fonctionnalité intéressante de VisualVM est la possibilité de faire un snapshot des moniteurs à un instant donné et de pouvoir y revenir à n’importe quel moment.

    Juste une petite précision sur la manière dont VisualVM collecte les données sur des JVM distantes. Il y a 2 possibilités, soit on utilise effectivement la connexion JMX, soit on se connecte via un démon jstatd qui tourne sur la même machine que la (les) JVM à surveiller.

    L’avantage de ce dernier est qu’il présente toutes les JVM qui s’exécutent sur le serveur en question sans avoir à ajouter des paramètres à la ligne de commande de Java. Son défaut la difficulté à identifier la JVM qui nous intéresse dans le cas d’un serveur qui exécute un nombre important de JVM (les JVM sont simplement identifiées par leurs pid).

    Visiblement, il n’est pas possible de générer un heap dump à distance. La documentation précise que la génération n’est possible que sur les applications locales : https://visualvm.dev.java.net/heapdump.html.

    De même, le plugin sampler pour profiler l’application n’autorisera pas l’analyse de la mémoire sur une JVM distante. En revanche, je n’ai aucuns soucis avec VisualGC.

    Enfin, l’analyse des heap dump est (un peu près) le seul domaine où je fais une infidélité à VisualVM en utilisant Eclipse Memory Analyzer qui est quand même beaucoup plus joli : http://www.eclipse.org/mat/.

  7. Sinon quelqu’un a testé ces outils sur une JRE 1.4 ?

    Pour le monitoring des JVM distantes, je ne pense pas que ça a un réel intérêt à part si vous avez des serveurs Tomcat en production ^_^. En plus, c’est rare qu’on nous ouvre un port pour y connecter un outil de monitoring (JConsole ou VisualVM)

    Sinon, pour le monitoring distant, généralement on utilise des serveurs d’applications qui sont en général JBoss, Jonas ou Websphere.

    Pour Jonas, il dispose d’un outil de monitoring équivalent dans sa console d’administration.
    Pour Websphere, il y a Tivoli qui est inclut aussi dans la console d’administration mais qui est très complet (informations sur les temps de réponse des servlets, pool de connexion, etc.)

    Au final, avec c’est outils, comment fait-on pour ‘tuner’ les JVM ?
    Déjà, il faudrait que les serveurs d’applications utilisent tous la même JVM…(ce qu’il n’est pas le cas d’IBM)

    Sinon ça reste intéressant pour voir les fuites mémoires en phase de développement.

  8. Pour la JRE 1.4, c’est un petit peu plus compliqué car le support complet de JMX n’apparait effectivement que dans Java 5.0. Cependant, certain ont réussi (avec plus ou moins de succès) mais uniquement pour naviguer dans les MBeans qu’ils avaient déclaré. En effet, la JVM 1.4 elle même n’est pas exposée sous forme de MBean, donc il n’y aura pas de joli graphe avec la consommation mémoire et tout ce qui s’en suit dans la JConsole.

    Personnellement (mais ça n’engage que moi), je pense que le monitoring distant est vraiment quelque chose d’utile. Sur un projet important, l’environnement de production n’est pas forcément le seul à être distant et exploité par un tiers hébergeur. Cela peut passer par un environnement de recette fonctionnelle (quand il n’y en a qu’un seul), un environnement d’intégration, des environnements de pré-production et de performance (souvent proche de la production).

    Là où je te rejoins, c’est que ces outils ne sont effectivement que des outils d’analyse à un instant donné. Et donc, j’y vois 2 applications : les développeurs pour voir le résultat de leur ouvrage et les interventions en mode pompier pour comprendre la cause d’un problème (et là, un VisualVM ou Jconsole qui donne directement le résultat des Thread Dump, c’est tout bonnement génial). Pour une surveillance dans le temps, ce ne sont plus des outils adaptés, il vaut mieux utiliser des consoles qui centralisent et stockent les données collectées (via JMX ou autres méthodes) comme Introscope par exemple.

    Il manque Weblogic sur la liste qui a aussi pas mal d’information sur la santé des serveurs dans sa console d’administration mais que je ne trouve pas aussi complet qu’un VisualVM associé au plugin sampler pour le profiling par exemple.

  9. Arnaud, quand tu utilises VisualGC sur une JVM distante, celle-ci est accessible par la connexion JMX ou pas Jstatd?

    Sinon il ne faut pas oublier qu’on peut faire tourner des applications Java sans serveur d’application. Les monitorer à distance peut être utile.

    Dans mon cas, grâce à VisualVM, j’ai pu étudier la consommation mémoire de programme de batch écrits en Java.

  10. J’ai effectivement l’impression que VisualGC ne fonctionne qu’avec jstatd.
    En fait, je pense qu’il y a un petit bug : si tu as les 2 types de connexions pour la même JVM (je sais que c’est inutile mais c’était pour les tests) et si tu te connecte en premier via jstatd puis via JMX alors VisualGC via JMX semble fonctionner alors qu’il ne fonctionne pas du tout en se connectant via JMX en premier.
    Encore un problème existentiel d’informaticien !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.