Criação fácil de perfis Java na linha de comando

Ou: “Meu Java está demorando muito / fica sem memória, como é ??”

Portanto, tenho um aplicativo Java que está sendo executado um pouco lento.
Eu poderia ir até o fim e jogar VisualVMatrás dele para ter uma boa GUI para tentar criar um perfil, mas o aplicativo está sendo executado em um servidor remoto e não estou com vontade de abrir portas RMI e sei lá o quê.

Perfil rápido e sujo

Tempo de CPU

Para usar o HPROF para obter rapidamente uma imagem do que está levando todo o tempo no aplicativo, executamos o Java VM com os seguintes parâmetros:

java -agentlib:hprof=cpu=samples RecursiveClustering

Isso dirá ao HPROF para coletar informações de uso da CPU por threads de amostragem. Teremos então um arquivo de saída java.hprof.txtcontendo o resultado da análise solicitada.

Incluí uma amostra do meu perfil aqui:

CPU SAMPLES BEGIN (total = 21079) Mon May 20 12:31:57 2013
rank
self accum count trace method
1 27.80% 27.80% 5859 300304 java.lang.StrictMath.acos
2 24.52% 52.32% 5169 300275 java.net.SocketInputStream.socketRead0
3 6.49% 58.81% 1369 300349 java.lang.String.length
4 5.19% 64.01% 1095 300407 java.util.regex.Pattern$Branch.match
5 3.57% 67.58% 753 300315 java.util.Vector.indexOf
6 3.51% 71.08% 739 300311 java.util.Vector.contains
7 3.04% 74.13% 641 300308 DBscanDistanceMatrix.getNeighboursWithinRange
8 2.25% 76.38% 475 300443 java.util.regex.Matcher.getTextLength
9 1.75% 78.13% 368 300446 java.util.regex.Pattern$Curly.match
10 1.43% 79.56% 302 300416 java.util.regex.Pattern$Start.matcho

Podemos ver isso java.lang.StrictMath.acose java.net.SocketInputStream.socketRead0somos responsáveis ​​por 52% do tempo da CPU. Talvez eu tente não ligar acostanto ou otimizar meu banco de dados. 🙂

Esses números são criados por amostragem dos fios. Se quiséssemos um resultado mais preciso, poderíamos usar -agentlib:hprof=cpu=times.
Esta opção injeta código em cada entrada e saída de método, acompanhando as contagens exatas de chamadas de método e o tempo gasto em cada método.
Muito preciso e muito lento .. !!

HEAP Dump – usando HAT

HPROF também é capaz de criar dumps de heap. Podemos habilitar isso usando o seguinte:

java -agentlib:hprof=heap=dump RecursiveClustering

O arquivo de texto resultante é grande e assustador! Portanto, em vez disso, usamos o seguinte e informamos ao HPROF para formatar o resultado como dados binários.

java -agentlib:hprof=heap=dump,format=b RecursiveClustering

Agora podemos usar a ferramenta chamada jhat– Java Heap Analysis Tool.

jhat java.hprof

Isso iniciará um servidor web na máquina, permitindo-nos navegar pelas classes java e instâncias de objetos usando a memória quando o dump foi criado.

Referências

Uma explicação limpa e agradável de criação de perfil com HPROF por RJ Lorimer:

Ferramentas: Use HProf para assistência rápida e suja de criação de perfil

Oracle Docs:

Oracle docs HPROF

Oracle docs jhat