Le profilage Java est le processus de surveillance de divers paramètres de niveau JVM tels que l’exécution des méthodes, l’exécution des threads, la création d’objets et la collecte des déchets.Vous pouvez obtenir les thread dumps comme un fichier journal de tous les processus qui s’exécutent dans la JVM.Un thread dump est un instantané de l’état de tous les threads qui font partie du processus spécifique.
Sous linux en donnant la commande ‘jps’ (JVM process status tool) vous pouvez obtenir les machines virtuelles Java HotSpot instrumentées (JVM) sur le système cible avec leur ID de processus correspondant.
Figure 1- JVMs et leurs pids.
La commande ‘jps -l ‘ sort le nom complet du package de la classe principale de l’application ou le nom complet du chemin d’accès au fichier JAR de l’application.Reportez-vous à la documentation de jps pour plus d’informations.
Après cela, nous pouvons utiliser la commande ‘jstack’ pour capturer les dumps de threads. L’outil jstack est livré dans le dossier JDK_HOME/bin. Voici la commande que vous devez lancer pour capturer le dump des threads:jstack <pid>. Ici pid est l’ID du processus de l’application, dont le thread dump doit être capturé. Ainsi, ‘jstack 13626’ dans ma console produira le journal suivant de thread dumps comme indiqué dans la figure.
Outils de profilage intégrés et leur mise en œuvre
En plus de ceux-ci, il existe divers outils intégrés pour faire le profilage de la JVM comme Java VisualVM,Honest Profiler, Async Profiler et Java Mission Controller
Avant d’entrer dans la profondeur de ces profileurs, nous devons connaître le concept de ‘Safe point’. La JVM s’occupe en interne de beaucoup de choses pour nous, comme la Garbage Collection et la compilation JIT. La JVM a donc aussi besoin de son propre temps pour régler certaines choses pour elle-même, en dehors de l’application. Certaines des choses que la JVM peut faire peuvent impliquer un point de sécurité (y compris GC). Pendant un safepoint, tous les threads exécutant du code Java sont suspendus pour permettre à la JVM de faire son travail. L’application s’arrête pendant le temps où la JVM passe à un safepoint.Ainsi, certains profilers souffrent de ces problèmes de safepoint où ils donnent un callback aux threads spécifiés ,ces threads devraient être dans un safepoint pour répondre à ce callback.Ainsi, cela affecte les performances.
D’autre part, certains profilers utilisent un appel API interne openJDK AsyncGetCallTrace (ASGT) pour faciliter la collecte non-safepoint des traces de pile. AsyncGetCallTrace n’est PAS une API officielle de la JVM. Pour utiliser ASGT, créez d’abord un agent JVMTI. L’interface Java Virtual Machine Tool Interface (JVMTI) fournit une interface de programmation qui vous permet, en tant que développeur de logiciels, de créer des agents logiciels capables de surveiller et de contrôler vos applications en langage de programmation Java.Ce signal sera dirigé vers la JVM en cours d’exécution et l’un de leurs threads en cours d’exécution sera interrompu et rappellera notre gestionnaire de signal.Assurez-vous que le thread interrompu est en cours d’exécution dans votre gestionnaire de signal et appelez l’AGCT.Honest profiler utilise cet ASGT pour faire du profilage.
Le profiler Honest a deux parties à lui. Un agent JVMTI C++ qui écrit un fichier contenant toutes les informations de profilage sur l’application à laquelle l’agent jvmti a été attaché.La deuxième partie, est une application Java qui rend un profil basé sur ce journal qui a été précédemment généré.
La méthode ASGT ressemblera à ceci . AsyncGetCallTrace(ASGCT_CallTrace *trace,jint depth,void* ucontext) .Nous devrions passer un pointeur vers la trace d’appel ASGT à cette méthode.
Le problème avec cette approche est que vous obtenez des données légèrement différentes d’une trace de pile Java typique. Le profileur doit les traiter et les faire correspondre aux lignes du code source pour être utile.
Le profileur asynchrone est un profileur d’échantillonnage à faible coût qui fonctionne en attachant un agent Java natif à un processus JVM en cours d’exécution et en collectant les échantillons de traces de pile en utilisant des API spécifiques à HotSpot. Async-profiler fonctionne uniquement sur GNU/Linux et MacOS, et sur le premier, il utilise en plus perf_events pour creuser dans le code natif également. L’approche générale est de recevoir les piles d’appels générées par perf_events et de les faire correspondre avec les piles d’appels générées par AsyncGetCallTrace, afin de produire un profil précis du code Java et natif. Il utilise l’API perf_events pour configurer l’échantillonnage du CPU dans un tampon mémoire, et demande qu’un signal soit délivré lorsqu’un échantillon se produit. Le gestionnaire de signaux appelle ensuite l’AGCT et fusionne les deux piles : la pile Java, capturée par l’AGCT, et la pile native + noyau, capturée par perf_events. Pour les threads non-Java, seule la pile perf_events est conservée.
Java Mission Controller(JMC) donne un rapport détaillé de chacun des threads spécifiques dans chaque JVM et leur pourcentage de consommation de CPU d’une manière efficace.Java Mission Control fonctionne en interagissant avec un agent JMX dans la JVM qui a un serveur MBean qui s’intègre avec la VM intégrée et l’instrumentation de l’app exécutant le dans la JVM. Il s’agit d’un avantage clé, car il permet de réduire les frais généraux de l’outil en utilisant des crochets préexistants. Oracle déclare que ce coût est normalement bien inférieur à 1%, et qu’il n’y a rien que vous deviez installer ou attacher à votre VM existante pour le faire fonctionner. Avec Flight recorder, il y a quelques drapeaux que vous devez activer, mais rien à installer. Démarrez un terminal, allez dans le répertoire bin de votre JDK et tapez simplement jmc.JMC affichera une interface graphique contenant vos JVM en cours d’exécution.Sélectionnez le processus JVM que vous devez profiler et commencez à enregistrer en spécifiant la limite de temps.
Une autre alternative populaire est l’utilisation de Linux perf, qui ne supporte pas directement Java mais a un grand support pour profiler le code natif, et n’a pas de problème à regarder les piles du noyau également. Pour la prise en charge de la JVM, nous avons besoin d’une carte perf qui fait correspondre les adresses compilées par JIT aux noms de fonctions (en corollaire, seules les trames compilées sont prises en charge ; les trames de l’interpréteur sont invisibles)
Et un commutateur JIT -XX:+PreserveFramePointer qui s’assure que perf peut parcourir la pile Java. En utilisant ce genre d’approche, vous finissez par perdre des cadres d’interpréteur.Vous ne pouvez pas profiler une ancienne JVM qui n’a pas le drapeau PreserveFramePointer.Il peut y avoir des entrées périmées dans votre perfmap parce que le JIT peut recompiler le code.Comme le JIT jette du code, certaines fonctionnalités peuvent finir par être avec une implémentation incorrecte.
En plus de ceux-ci, la Java 2 Platform Standard Edition (J2SE) a toujours fourni un outil de profilage simple en ligne de commande appelé HPROF pour le profilage du tas et du cpu. HPROF est un outil intégré au JDK pour le profilage de l’utilisation du CPU et du tas au sein d’une JVM.HPROF est en fait une bibliothèque d’agent natif de la JVM qui est chargée dynamiquement par le biais d’une option de ligne de commande, au démarrage de la JVM, et devient une partie du processus de la JVM. En fournissant des options HPROF au démarrage, les utilisateurs peuvent demander à HPROF différents types de fonctions de profilage du tas et/ou du processeur. Les données générées peuvent être au format textuel ou binaire, et peuvent être utilisées pour repérer et isoler les problèmes de performance impliquant l’utilisation de la mémoire et un code inefficace. Le fichier au format binaire de HPROF peut être utilisé avec des outils tels que HAT pour parcourir les objets alloués dans le tas.
Conclusion
Nous observons que le profilage honnête et le profilage Async ont surmonté l’anomalie de ‘Souffrir de points de sécurité’ par un appel d’API interne d’openJDK AsyncGetCallTrace.Ils peuvent effectuer le profilage avec beaucoup moins de frais généraux que les outils de profilage standard. Mais ils ne peuvent pas fournir un profilage détaillé des threads qui sont spécifiques aux processus de la JVM séparément. Ils peuvent seulement produire un fichier journal/une interface utilisateur de l’ensemble des vidages de threads.D’autre part, Java Mission Control peut profiler les threads qui sont spécifiques à chaque processus séparément où vous pouvez surveiller les threads chauds avec leur utilisation du CPU.Ainsi, JMC est la meilleure option pour surveiller les paramètres de la JVM avec beaucoup de granularité.
Références.
Java Virtual Machine Process Status Tool Oracle Documentation.
https://docs.oracle.com/javase/7/docs/technotes/tools/share/jps.html
Création d’un agent de débogage et de profilage avec JVMTI
http://www.oracle.com/technetwork/articles/java/jvmti-136367.html
Les avantages et les inconvénients des profileurs AsyncGetCallTrace
http://psy-lob-saw.blogspot.com/2016/06/the-pros-and-cons-of-agct.html
Un profileur JVM d’échantillonnage sans le biais d’échantillonnage safepoint-.Honest Profiler
https://github.com/jvm-profiling-tools/honest-profiler
Profiler d’échantillonnage CPU et HEAP pour Java comprenant AsyncGetCallTrace + perf_events
https://github.com/jvm-profiling-tools/async-profiler
.