Comment trouver des hotspots dans une application Web java (exécutée dans Tomcat)?


J'ai une application Web qui prend plus de temps qu'elle ne le devrait pour effectuer une tâche spécifique. Je place l'application Web sous charge en utilisant ab avec une simultanéité d'un, et je vois tomcat utiliser 100% d'un CPU. Je veux explorer l'application et répondre à la question " que fait ce code java pour que le code java brûle 100% d'un processeur?".

J'ai essayé d'utiliser Java Flight Recorder comme suit pour enregistrer mon application en plein vol comme suit:

-sh-4.1$ jcmd 115388 JFR.start duration=60s filename=/tmp/app-service-live.jfr settings=profile

Charger le fichier JFR résultant dans VisualVM me donne ce qui suit:

Capture d'écran de l'onglet Échantillons de CPU VisualVM

Comme on peut le voir dans la capture d'écran, bien qu'un seul thread soit rouge pendant l'enregistrement, tous les threads sont marqués comme rouge. En pénétrant dans l'un des fils chauds, VisualVM nous signale que le soleil brûle.misc.Dangereux.park() la méthode. Cette méthode n'est pas rouge, mais pierre froide.

Sans aucun moyen de faire la différence entre le code chaud contribuant pour le chiffre du processeur à 100% et le code stone cold bloqué en attente d'un événement externe, il n'y a pas d'image cohérente qui émerge.

Quelles modifications dois-je apporter à ma ligne de commande jcmd pour capturer correctement ce que fait le CPU?

Quel processus alternatif dois-je suivre dans VisualVM pour trouver du code chaud, tout en éliminant le code froid?

Author: Graham Leggett, 2020-10-29

1 answers

Je n'ai pas vu l'implémentation de Visual VM, mais l'événement que les échantillons sur CPU s'appelle jdk.ExecutionSample.

Il y a aussi un jdk.Événement NativeMethodSample qui peut être utilisé pour trouver des threads bloqués en natif, mais il n'est pas possible pour la JVM de déterminer s'ils sont en cours d'exécution ou non, ils ne doivent donc pas faire partie de la visualisation.

Si c'est le cas, vous pouvez contourner le bogue en utilisant JDK Mission Control ou modifier la configuration pour que l'événement ne soit pas enregistré. Regardez dans le répertoire JAVA_HOME/lib / jfr et copiez la valeur par défaut.jfc à un nouveau fichier, c'est-à-dire mon.jfc, puis changer dans le fichier de sorte que le jdk.L'événement NativeMethodSample a le paramètre:

<setting name="enabled">false</setting>

Puis exécutez-le comme ceci:

$ jcmd <pid> settings=my duration=60s ...

Vous pouvez également copier la configuration dans un autre répertoire, mais vous devez alors spécifier le chemin complet:

$ jcmd <pid> settings=/conf/my.jfc duration=60s ...
 0
Author: Kire Haglin, 2020-10-30 20:55:15