Come faccio a trovare gli hotspot in un'applicazione Web java (in esecuzione in Tomcat)?


Ho un'applicazione Web che richiede più tempo di quanto dovrebbe per eseguire un'attività specifica. Metto l'applicazione Web sotto carico usando ab con una concorrenza di uno, e vedo tomcat usare il 100% di una CPU. Voglio approfondire l'applicazione e rispondere alla domanda "cosa fa questo codice java per far sì che il codice java masterizzi il 100% di una CPU?".

Ho provato ad usare Java Flight Recorder come segue per registrare la mia applicazione in volo completo come segue:

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

Il caricamento del file JFR risultante in VisualVM mi dà quanto segue:

Schermata della scheda campioni CPU di VisualVM

Come si può vedere nello screenshot, nonostante un solo thread sia rosso caldo durante la registrazione, tutti i thread sono contrassegnati come rosso caldo. Drilling giù in uno dei fili roventi, VisualVM ci riporta come bruciore caldo all'interno del sole.varie.Pericoloso.parco () metodo. Questo metodo non è rovente, ma freddo di pietra.

Senza modo di dire la differenza tra il contributo di hot code per la cifra CPU 100% e il codice stone cold che viene bloccato in attesa di un evento esterno, non esiste un'immagine coerente che emerge.

Quali modifiche devo apportare alla mia riga di comando jcmd per acquisire correttamente ciò che sta facendo la CPU?

Quale processo alternativo devo seguire all'interno di VisualVM per trovare il codice caldo, eliminando il codice freddo?

Author: Graham Leggett, 2020-10-29

1 answers

Non ho visto l'implementazione di Visual VM, ma l'evento che campiona sulla CPU si chiama jdk.ExecutionSample.

C'è anche un jdk.Evento NativeMethodSample che può essere utilizzato per trovare thread bloccati in nativo, ma non è possibile per la JVM determinare se sono in esecuzione o meno, quindi non dovrebbero far parte della visualizzazione.

Se lo è, puoi aggirare il bug usando JDK Mission Control o modificare la configurazione in modo che l'evento non lo sia registrare. Cerca nella directory JAVA_HOME / lib / jfr e copia il valore predefinito.jfc a un nuovo file, cioè il mio.jfc, e poi cambiare nel file in modo che il jdk.L'evento NativeMethodSample ha l'impostazione:

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

Quindi eseguilo in questo modo:

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

È anche possibile copiare la configurazione in un'altra directory, ma è necessario specificare il percorso completo:

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