Diagnostic d’une JVM à distance

Développer une application Java, c’est bien. La rendre performante, c’est mieux.

Cependant, qui dit « performance », dit « mesure ». En effet, il est nécessaire de pouvoir :

  • connaître les paramètres de lancement de la JVM,
  • mesurer l’empreinte mémoire et le comportement du Garbage Collector,

Cet article va décrire dans une première partie les différents outils permettant de collecter ces informations en local. La seconde partie se concentre sur les moyens pour obtenir ces mêmes informations à distance.

En local…

Au fur et à mesure des différentes versions et afin d’obtenir les meilleures performances, la machine virtuelle Java (JVM) s’est dotée d’outils de diagnostic. Les principaux sont:

  • jps liste l’ensemble des JVM qui s’exécutent sur un système.
#jps -l
22791 weblogic.Server
18602 sun.tools.jps.Jps
5697 weblogic.Server
16937 activity.jar
6324 weblogic.Server
  • jstat affiche les statistiques d’une JVM sur sa gestion mémoire et le compilateur JIT.
#jstat -gcutil 16937 1s
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
  0.00  99.96   0.00  89.53  33.10   1274   71.231   194   69.937  141.167
 83.53   0.00  65.48  77.26  33.10   1275   71.285   194   70.610  141.895
 83.53   0.00  75.30  77.26  33.10   1275   71.285   194   70.610  141.895
 83.53   0.00  84.44  77.26  33.10   1275   71.285   194   70.610  141.895
 83.53   0.00  96.26  77.26  33.10   1275   71.285   194   70.610  141.895
  0.00  99.77   0.00  90.35  33.10   1276   71.391   195   70.610  142.001
  0.00   0.00   4.87   0.73  33.11   1276   71.391   195   70.749  142.140
  0.00   0.00  10.18   0.73  33.11   1276   71.391   195   70.749  142.140
  0.00   0.00  29.65   0.73  33.11   1276   71.391   195   70.749  142.140
  • jconsole est une application graphique Swing qui affiche des informations sur la mémoire, les threads, les classes et les MBeans.
  • visualvm est également une application graphique qui reprend les informations affichées par JConsole mais en allant plus loin (ex: Détection de Contentions Thread). Livré avec le JDK de sun depuis la version JDK 6 update 7, VisualVM pourrait avec le temps remplacer complètement JConsole
  • visualgc affiche sous forme graphique les informations que l’on peut obtenir sur le garbage collector avec jstat. cette application n’est pas packagée avec la jvm, elle est disponible séparément avec les outils jvmstat. de plus, elle fonctionne avec les jvm 1.4.

Et à distance … ?

Par défaut, tous ces outils doivent être lancés sur la système d’exploitation où s’exécute la JVM à diagnostiquer. Cependant les contraintes de sécurité des entreprises interdisent parfois d’accéder physiquement à la machine. Dans le meilleur des cas, il est possible d’obtenir une connexion distante (Windows RDP, Telnet ou SSH), mais souvent avec des niveaux d’accréditations trop faibles pour pouvoir exécuter les commandes listées ci-dessus. Alors comment faire ?

Sun a pensé à tout. Si on regarde de prés une distribution d’une JVM, on remarque un binaire de type démon ‘jstatd’.

  • jstatd est un démon qui surveille la création et la destruction des JVM et fourni une interface qui permet à des outils distants de se connecter aux JVM qui s’exécutent sur la machine. Exactement ce qu’il nous faut, non ?

Le moyen le plus simple est d’exécuter jstatd de la façon suivante:

#nohup jstatd -J-Djava.security.policy=all.policy &
#cat all.policy
grant codebase "file:${java.home}/../lib/tools.jar" {
   permission java.security.AllPermission;
};
#

A partir de ce moment, il est possible d’utiliser les logiciels présentés ci-dessus.

  • jps, en précisant le nom de la machine distante. Noter l’apparition d’un nouveau processus java: sun.tools.jstatd.Jstatd
D:xebia-blog>jps -l myremoteserver
5697 weblogic.Server
28636 sun.tools.jstatd.Jstatd
22791 weblogic.Server
29726 activity.jar
6324 weblogic.Server
  • jstatd et visualgc en précisant le virtual machine identifier avec le format lvmid@servername
D:xebia-blog>jstat -gcutil 29726@myremoteserver 1s
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
  0,00  99,78   0,00  83,38  33,14   8476  474,694  1227  445,801  920,495
  0,00  99,78   0,00  83,38  33,14   8476  474,694  1227  445,801  920,495
  0,00  78,41  77,46  42,98  33,14   8478  474,784  1227  446,133  920,917
 79,47   0,00  43,86  78,69  33,14   8481  474,971  1227  446,133  921,104
  0,00  82,64  76,48  63,39  33,13   8484  475,206  1228  446,649  921,855
  0,00  82,64  76,48  63,39  33,13   8484  475,206  1228  446,649  921,855
 85,47   0,00  77,78  74,92  33,13   8485  475,350  1228  446,649  921,999
  • Au lancement de visualvm, il suffit d’ajouter le nom du serveur ‘myremoteserver’ au noeud remote pour voir apparaître l’ensemble des JVM s’exécutant sur ce serveur. Il est possible alors de se connecter à l’une des machines virtuelles pour pouvoir avoir accès à:
  • Onglet Overview donne des informations générales (PID, Host, JVM Version, JVM Flags)
  • Onglet Monitor affiche des graphiques sur la consommation de ressources (Mémoire, Threads, …)

La copie d’écran suivante montre visualgc intégré sous forme de plugin dans visualvm

Cependant l’utilisation seule de jstatd n’est pas suffisante si l’on veut avoir accès aux MBeans JMX par jconsole et à l’activité des Threads avec visualvm. Il est nécessaire d’ajouter les paramètres suivants au démarrage de la JVM

-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

il est alors possible de connecter jconsole en utilisant la commande suivante:

D:xebia-blog>jconsole myremoteserver:9999

Avec l’outil visualvm, deux nouveaux onglets sont maintenant disponibles:

  • Onglet Threads affiche l’activité de l’ensemble des threads et permet d’obtenir facilement un thread dump
  • Onglet MBeans affiche l’ensemble des MBeans JMX

Conclusion

Vous êtes maintenant armés pour scruter votre application qui s’exécute dans votre JVM. Vouloir rendre votre application performante est une bonne idée. Cependant, l’expérience montre qu’il faut commencer absolument par analyser le code Java.
Exemple: Traitements inutiles ou redondants, accès à la base de données peu efficaces (trop ou pas assez de données manipulées),…
Il n’existe pas de paramètre magique dans la JVM (ou dans le Serveur d’application) qui permet à une application mal écrite de devenir performante.

Ce n’est que par la suite que l’on peut tuner la JVM. Si vous vous lancez dans cette aventure (passionnante) commencez par lire cet article de Kirk Pepperdine ,
My advice on JVM heap tuning, keep your fingers off the knobs!

10 Responses

  • VisualVM est effectivement intéressant car c’est un outil désormais intégré dans le JDK qui propose du tout-en-un et une architecture de plugins (basé sur NetBeans Platform). VisualGC existe d’ailleurs sous forme de plugin pour VisualVM. Il existe déjà plusieurs sortes de plugins comme celui pour GlassFish par exemple qui propose une vue par application déployée et d’autres infos propres au serveur d’application : https://visualvm.dev.java.net/plugins.html
    A chacun de créer son plugin VisualVM!

  • >> VisualGC existe d’ailleurs sous forme de plugin pour VisualVM

    La preuve en image dans l’article => http://blog.xebia.fr/wp-content/uploads/2008/10/visualvm-jstatd-visualgc-2.png

  • Excellent article.

  • j’adore aussi la fonctionalité plugin de la visualVM BTRACE à chaud , simplement enorme

  • Merci pour cet article fort intéressant.
    En effet je souhaiterais avoir la possibilité de monitorer mon JVM à distance mais je n’arrive pas à l’activer.
    En tapant:
    nohup jstatd -J-Djava.security.policy=all.policy &
    Voici ce que j’ai en sortie:
    n# nohup jstatd -J-Djava.security.policy=all.policy &
    [1] 22681
    nohup: ajout à la sortie de `nohup.out’

    et du coup j’ai:

    # ./jps -l 192.168.1.24
    RMI Registry not available at 192.168.1.24:1099
    Connection refused to host: 192.168.1.24; nested exception is:
    java.net.ConnectException: Connection refused

    en essayant de me connecter à distance.

    J’utilise JDK 1.6.0_07, Tomcat 6.0.16
    Merci d’avance!

  • Merci pour l’article, il est très utile
    J’essaie actuellment de connecter visualgc sur un tomcat fonctionnant en service via TOmcatService.exe mais impossible!
    Si quelqu’un a une idée, je suis intéressé

  • Sans messages d’erreur, difficile de t’aider. Il semble que tu fonctionnes sur Windows (TomcatService.exe): il peut y avoir alors quelque soucis avec NTFS. Google est ton ami! http://www.google.fr/search?q=jstat+ntfs

  • Seul problème de visualVM: il ne reconnecte pas en cas de perte de ligne :/. Embêtant lorsque l’on travaille avec un VPN que l’on déconnecte de temps en temps. Donc toujours JMX+jConsole pour moi (sauf en cas de nécessité bien sûr).

    Bon article en tous cas !

Laisser un commentaire