SlideShare uma empresa Scribd logo
1 de 6
Baixar para ler offline
a r t i g o
Diogenes Buarque Ianakiara
(diogenes.buarque@inmetrics.com.
br): Está cursando o último semestre de
Análise e Desenvolvimento de Sistemas
na FIAP. Trabalha com Java desde 2006.
Atualmente é analista de desempenho
na Inmetrics.
Muitas vezes, nos deparamos com problemas de performance nas aplicações
quedesenvolvemosourealizamosmanutenções.Amaiorpartedosproblemas
está relacionada com a má utilização ou insuficiência de memória. A solução
imediata de muitos é aumentar a memória alocada para a aplicação, ou
ainda, o número de nós do cluster do servidor de aplicação e finalmente o
hardware disponível. Isso tudo sem ao menos realizar uma avaliação prévia
do seu comportamento, buscando a causa-raiz dos problemas. Este artigo irá
apresentar a técnica de profiling, que visa analisar e identificar problemas
de performance em aplicações Java, utilizando a ferramenta JProfiler.
68 www.mundoj.com.br68
Aprenda como encontrar problemas de performance na sua
aplicação com o JProfiler.
Descobrindo o Profiling de
Aplicações Java com JProfiler
J ava Profiling é a técnica que visa analisar o desempenho de
aplicações coletando métricas e apresentando em tempo real a
porcentagem de utilização de threads, carga de objetos e tempo
de resposta dos métodos, possibilitando assim a identificação de gargalos e
oportunidades de otimização na aplicação.
Neste artigo apresentaremos um exemplo de profiling em uma aplicação
remota com a ferramenta JProfiler. Vamos desenvolver um EJB simples com
três serviços, que simularão um memory leak e um problema de consumo de
cpu. Não abordaremos os conceitos de EJB ou padrões de projetos para não
fugir do tema. Assim, iremos configurar o ambiente e o servidor de aplicação
para que possamos realizar o profiling.
Após a instalação, serão apresentadas as principais funcionalidades da ferra-
69
menta e o exemplo de uso de cada uma delas. O JProfiler irá se conectar
remotamente à aplicação desenvolvida e iremos por fim realizar a análise
e identificar o problema da aplicação.
O memory leak, ou vazamento de memória, ocorre
quando algum componente da nossa aplicação está
utilizando uma determinada quantidade de memória
para realizar alguma operação e, após finalizar esta
operação, este componente não libera a memória
utilizada. Geralmente isto ocorre devido a erros de pro-
gramação e pode levar ao consumo total da memória.
Instalação e configuração do JProfiler
O JProfiler é uma ferramenta paga, porém a ej-technologies, fornecedora
da ferramenta, oferece 10 dias de licença Trial, que até a data de escrita
deste artigo está na versão 5.2.3. O download pode ser realizado no site
http://www.ej-technologies.com/products/jprofiler/overview.html.
Configuração 1.1
Uma vez terminada a instalação padrão, a primeira execução apresentará
um wizard de inicialização rápida, para configurar o seu primeiro profi-
ling. Na primeira tela, selecione a opção de profiling em uma aplicação
local ou remota“An application Server, locally or remotely”, como mostra
a figura 1.
Figura 1. Selecionando o tipo de profiling.
Em seguida, será necessário seguir 11 etapas para configurar o profiling.
Na figura 2, é apresentada a primeira etapa, escolha o fornecedor e ver-
são do servidor de aplicação. Nesse caso, selecione JBoss 5.x.
Figura 2. Selecionando o servidor de aplicação.
Na segunda etapa, se a aplicação estiver no mesmo servidor em que
está instalado o JProfiler, selecione “On this computer”. Caso contrário,
selecione a plataforma remota. No nosso caso, selecionaremos “Linux/
AMD64”, como mostra a figura 3.
Na terceira etapa, existem três possibilidades:
connection from the JProfiler GUI”. Com esta opção, o JProfiler con-
figura o servidor de aplicação para que ele aguarde o JProfiler se
conectar antes de iniciar. Caso o JProfiler não se conecte, o servidor
de aplicação não será inicializado).
the JProfiler GUI”, O Jprofiler permite que o servidor inicie normal-
mente, possibilitando uma conexão futura com o JProfiler).
cannot connect”possibilita a realização do profiling em modo off-
line. Com esta opção, é possível configurar o servidor de aplicação
para gravar os dados do profiling em um arquivo e assim possibili-
tar uma análise off-line).
No nosso exemplo, vamos selecionar a opção iniciar imediatamente,
conforme a figura 4.
Figura 4. Selecionando o tipo de inicialização do Servidor de Aplicação.
Agora defina o endereço do servidor remoto, seguindo o exemplo da
figura 5.
Na quinta etapa, o JProfiler deve ser instalado no servidor. Para isto,
existe duas maneiras:
1 – Next, Next, Finish;
2 – Copiar os arquivos de uma instalação préexistente para a mesma
versão de SO.
O diretório da instalação deve ser informado nessa etapa, como mostra
a figura 6.
Na sexta etapa, precisamos informar o diretório onde estará o arquivo de
configuração de acesso remoto ao JProfiler, e é de extrema importância
para o sucesso do profiling. O nome deste arquivo é config.xml e ele será
gerado automaticamente ao final deste wizard no diretório “C:Docu-
ments and Settings<usuario>.jprofiler5config.xml” para a plataforma
Windows e“/home/<usuario>/.jprofiler5/”para a plataforma Linux/Unix.
Utilize a figura 7 como referência.
É possível observar na figura 8 que agora será necessário acessar o script
de inicialização do servidor de aplicação para o JProfiler configurar os pa-
râmetros de inicialização necessários. Para esta configuração, compartilhe
o diretório do servidor aplicação com as devidas permissões de escrita.
Assim, para o JBoss na plataforma Windows acesse o script run.bat no ou
run.sh na plataforma Linux/Unix. Após clicar em Next o JProfiler irá gerar
um novo script na mesma pasta indicada, chamado run_jprofiler.sh.
Figura 8. Acessando o script de inicializar do servidor.
No próximo passo, devemos informar fornecedor, versão do Java e o
modo de compilação, conforme a figura 9.
Como é apresentado na figura 10, o JProfiler utiliza a configuração de-
fault, para definir a porta de comunicação. A mesma pode ser alterada
caso já esteja em uso.
Aqui finalizamos nossa configuração, podemos visualizar as informações
sobre este profiling e todos os cuidados que devemos ter antes de iniciar
o profiling, como mostra a figura 11. Na 11ª etapa, você pode escolher
entre iniciar imediatamente o profiling ou deixar para depois.
Figura 11. Finalizando a configuração do profiling.
O processo de profiling geralmente é muito oneroso para o
processador. Por isso é importante definir um período curto
para a execução do profiling. Outro fator importante é o
nível de detalhamento do profiling que deve ser definido
antes de sua execução, o nível médio é recomendado para
CPU e o baixo para memória. Caso seu servidor esteja com
folga no uso de memória e CPU, estes níveis podem ser
alterados conforme sua necessidade.
70 www.mundoj.com.br
Para podermos executar o profiling, vamos desenvolver uma miniaplica-
ção que simulará o consumo de CPU e o Memory leak. Construiremos um
EJB contendo três serviços. O primeiro serviço simulará um vazamento
de memória, o segundo simulará o processamento de uma request sim-
ples e, por ultimo, teremos um método que terá a uma maior alocação
de memória e processamento, entretanto não possuirá vazamento de
memória.
Implementação dos serviços 1.1
A Listagem 1 apresenta uma condição de errada no segundo "for", de-
vido memory leak que o objeto string tem em cada iteração. Se fosse
um registro de um banco de dados, este vazamento poderia resultar em
uma falta de resposta da aplicação e esgotar rapidamente da memória
disponível.
public void memoryLeak(int iter, int count) {
for (int i=0; i<iter; i++) {
for (int n=0; n<count; n++) {
memoryVector.add(Integer.toString(n+i));
}
for (int n=count-1; n>0; n--) {
memoryVector.removeElementAt(n);
}
}
}
public void noMemoryLeak (int size) {
HashSet tmpStore = new HashSet();
for (int i=0; i<size; ++i) {
String leakingUnit = new String(“Object: “ + i);
tmpStore.add(leakingUnit);
}
}
}
public void requestMemoryLeak(int iter) {
Random requestQueue = new Random();
for (int i=0; i<iter; i++) {
int newRequest = requestQueue.nextInt();
pendingRequests.add(new Integer(newRequest));
}
}
Listagem 1. Implementação do método memoryLeak.
Listagem 3. Implementação do método noMemoryLeak.
Listagem 2. Implementação do método requestMemoryLeak.
A Listagem 2 apresenta um caso muito comum, quando uma requi-
sição de entrada é mantida em uma hash table até que a mesma seja
concluída, exceto neste exemplo, deixamos de propósito um erro de
programação, no qual não removemos do hash table os objetos que
foram inseridos anteriormente. Durante um período de tempo, a hash
table terá um grande número de alocações, o que resultará em muitas
colisões, bem como uma grande parte da pilha ocupada por entradas
inúteis. Ambas as listagens são casos muito comuns que resultam em
memory leaks.
Podemos pensar que os locais de maior alocação de memória são os
dois métodos anteriores. No entanto, isso não é verdade. Por exemplo,
na Listagem 3, o método noMemoryLeak aloca uma grande quantidade
de memória, porém tudo isso é coletado pelo GC (Garbage Collector),
deixando a memória sempre disponível. Por outro lado, os outros dois
métodos que não alocam muita memória estão causando constante-
mente memory leaks.
Realizando o profiling e identificando
o problema
Primeiramente vamos abrir o JProfiler e selecionar a opção“Start Center”.
Dentre as opções disponíveis, selecione a opção que você configurou no
primeiro tópico, e clique em Start. Conforme a figura 12.
Figura 12. Selecionando a o profiling configurado.
O wizard apresentado na figura 13 dá a possibilidade de configurar os
níveis de detalhamento do profiling, iremos utilizar os níveis recomen-
dados para não degradar o ambiente testado. Clique em ok para iniciar
o profiling.
Agora vamos iniciar nossa aplicação cliente, que por sua vez consumirá
os serviços do nosso componente MemoryLeakEJB. A Listagem 4 apre-
senta o código que simulará a utilização dos serviços disponíveis. Inicie
a aplicação cliente.
7171
public static void main(String[] args) {
Properties properties = new Properties();
properties.put(“java.naming.factory.initial”,”org.jnp.interfaces.
NamingContextFactory”);
properties.put(“java.naming.factory.url.pkgs”,”=
org.jboss.naming:org.jnp.interfaces”);
properties.put(“java.naming.provider.url”,”10.10.11.97:1099”);
try
{
Context context = new InitialContext(properties);
MemoryLeakRemote memoryLeakRemote =
(MemoryLeakRemote) context.lookup(MemoryLeakBean.
RemoteJNDIName);
for (int i=0; true; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(“iteração nº: “ + i);
memoryLeakRemote.slowlyLeakingVector(1000,10);
memoryLeakRemote.leakingRequestLog(5000);
memoryLeakRemote.noLeak(100000);
}
} catch (NamingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
Listagem 4. Implementação de uma aplicação Cliente.
Identificando problemas de vazamento de memória
Neste momento, o JProfiler está conectado com o nosso servidor de
aplicação. A primeira métrica que o JProfiler nos apresenta é a“Memory
Views”. Estes dados dão a possibilidade de visualizar os níveis de agre-
gação, podemos selecionar os níveis Class, Packages, J2EE Components.
Para nosso exemplo, selecionaremos J2EE Components. Esta opção apre-
senta os componentes JEE mais utilizados no App Server, geralmente
ele também apresenta componentes do próprio servidor de aplicação,
porém podemos observar na figura 14 que dentre eles encontramos o
nosso componente“MemoryLeakBean”.
Figura 14. Visualizando métricas de memória da Aba All Objects.
As abas da parte inferior nos apresentam métricas diversificadas do uso
de memória no servidor de aplicação. Ao selecionar uma aba, será apre-
sentado um botão ao qual será possível iniciar o monitoramento que
desejamos. Para nosso exemplo, vamos utilizar apenas as aba inicial, All
Objects e Allocation Call Tree.
O ideal é avaliar um item por vez, seja ele memória, CPU,
threads, ou snapshots. Para não degradar totalmente o
ambiente. Uma que você iniciou uma avaliação é impor-
tante armazenar todas as evidências do que foi analisado,
para futuras comparações, como também para um históri-
co do comportamento da aplicação.
Após identificar que o componente MemoryLeakBean está na lista de
objetos da aba All Objects, selecione a aba Allocation Call Tree. Esta aba
apresentará uma árvore de utilização da memória.
Como podemos observar na imagem da figura 15, os métodos do
componente MemoryLeakBean consomem aproximadamente 50% do
tempo de uso e alocação de memória, especialmente o método noLeak.
AgoravamosselecionaraopçãoVMTelemetryViews.Estaopçãoapresen-
tará gráficos de utilização da Heap, Thread e até CPU load. Ao selecionar
pela primeira vez esta opção, já podemos observar um comportamento
incomum da Heap. Notamos na figura 16 que este comportamento re-
presenta um memory leak ou vazamento de memória.
Indo mais a fundo, vamos selecionar a aba GC Activity, que nos apresen-
tará um gráfico da atividade do Garbage Collector. Podemos notar na fi-
gura 17 uma intensa atividade de GC, este comportamento se dá quando
possuímos muitos novos objetos alocados, preenchendo todo espaço da
Heap. Caso não haja mais memória para alocação, será lançado o“velho
e conhecido”erro java.lang.OutOfMemory.
72 www.mundoj.com.br
Figura 17. Visualizando o gráfico de atividade do GC.
Identificando problemas de consumo de CPU
A opção CPU Views apresenta detalhadamente a árvore de uso de CPU.
Podemos observar na figura 18 que 95% da utilização de CPU está alo-
cada nos três métodos que estamos consumindo. Podemos filtrar ainda
mais utilizando a opção Thread status. Esta opção fornece a visualização
detalhada do uso de classes e métodos por estado de cada thread, seja
ele blocked, running ou waiting.
Figura 18. Visualizando a árvore de consumo de CPU.
As abas Hot Spots apresentam tanto para memória ou CPU pontos que
possivelmente podem ser críticos, porém estas métricas requerem um
maior nível de detalhamento do profiling. Muitas vezes estas métricas
podem apresentar resultados genéricos, como java.lang.String ou java.
lang.Integer, entretanto, se você possuir um método muito oneroso para
o sistema, ele com certeza aparecerá nesta análise. Como podemos ob-
servar o método noLeak da figura 19.
Figura 19. Visualizando possíveis pontos de interesse.
Após identificar as causas de um problema de performance, deve-se ana-
lisar profundamente o problema para se obter a melhor solução. Muitas
vezes estes problemas podem ser resolvidos com otimizações do código,
porém nem sempre podemos alterar o mesmo, por exemplo, quando o
código não nos pertence. Outros problemas podem ser resolvidos com
o tuning da JVM.
Tuning da JVM é o ato de otimizar o uso do garbage
collector para que ele seja executado de forma mais efi-
ciente, possibilitando assim um ganho de performance
na aplicação.
Não está no escopo do artigo se aprofundar em como resolver os pro-
blemas de performance ou como desenvolver um EJB. Todos os códigos
estarão disponíveis no site http://www.mundoj.com.br.
Sabermais
Na edição 35 da revista Mundoj o artigo “Co-
nhecendo os parâmetros de configuração mais
utilizadosdaJVM”apresentoutécnicasdecomo
otimizaraJVM.
Considerações finais
Neste artigo foi apresentadas algumas formas de identificar problemas
de performance em aplicações Java utilizando a técnica de profiling. Esta
técnica está fortemente ligada ao ciclo de vida das aplicações, uma vez
que uma aplicação já nasce com problemas de performance, certamente
estes problemas só irão aumentar. Assim buscamos apresentar não só os
conceitos do profiling, mas também um exemplo prático de como iden-
tificar esses problemas.
No primeiro tópico apresentamos como configurar a ferramenta e cons-
truir um profiler remoto, seguindo, construímos duas aplicações, um
EJB que simulou problemas de memory leak e cpu load e uma aplica-
ção cliente que por sua vez consumiu todos os serviços do EJB. Assim,
aprendemos como iniciar um profiling visualizando métricas de memória
e cpu e como identificar não só o componente, mas também a classe e os
métodos que apresentavam os problemas de performance. É importante
salientar que apenas identificando o gargalo não necessariamente o
problema estará resolvido. É preciso analisar e evidenciar para se chegar
Referências
7373

Mais conteúdo relacionado

Mais procurados

400 Dicas Xp.Erivanildo.Thegenius.Us
400 Dicas Xp.Erivanildo.Thegenius.Us400 Dicas Xp.Erivanildo.Thegenius.Us
400 Dicas Xp.Erivanildo.Thegenius.Ussifja
 
06 breve histórico do action script - Flash 8
06 breve histórico do action script - Flash 806 breve histórico do action script - Flash 8
06 breve histórico do action script - Flash 8Reuel Lopes
 
Tratamento de exceções com PHP
Tratamento de exceções com PHPTratamento de exceções com PHP
Tratamento de exceções com PHPLeonardo Soares
 
C:\Fakepath\Manual Antivirus
C:\Fakepath\Manual AntivirusC:\Fakepath\Manual Antivirus
C:\Fakepath\Manual AntivirusPlanilhao
 
Testes de Software - Módulo 3
Testes de Software - Módulo 3Testes de Software - Módulo 3
Testes de Software - Módulo 3Rodrigo Paes
 
Remover ViluciWare Ransomware
Remover ViluciWare RansomwareRemover ViluciWare Ransomware
Remover ViluciWare RansomwareMarkRutherford10
 
PHPUnit e teste de software
PHPUnit e teste de softwarePHPUnit e teste de software
PHPUnit e teste de softwarericardophp
 
Funções R-statistic
Funções R-statisticFunções R-statistic
Funções R-statisticErnani Vilela
 
Testes de Software - Módulo 2
Testes de Software - Módulo 2Testes de Software - Módulo 2
Testes de Software - Módulo 2Rodrigo Paes
 
Remover Saved (Scarab) Ransomware
Remover Saved (Scarab) RansomwareRemover Saved (Scarab) Ransomware
Remover Saved (Scarab) RansomwareMarkRutherford10
 
Remover ArisLocker Ransomware
Remover ArisLocker RansomwareRemover ArisLocker Ransomware
Remover ArisLocker RansomwareMarkRutherford10
 
Java recursos avançados - multithreading
Java   recursos avançados - multithreadingJava   recursos avançados - multithreading
Java recursos avançados - multithreadingArmando Daniel
 
Sistemas Operacionais - Aula 07 (Thread e Processos)
Sistemas Operacionais - Aula 07 (Thread e Processos)Sistemas Operacionais - Aula 07 (Thread e Processos)
Sistemas Operacionais - Aula 07 (Thread e Processos)Leinylson Fontinele
 
Testes de unidade e TDD SoLiSC 2011
Testes de unidade e TDD SoLiSC 2011Testes de unidade e TDD SoLiSC 2011
Testes de unidade e TDD SoLiSC 2011Luís Cobucci
 

Mais procurados (19)

400 Dicas Xp.Erivanildo.Thegenius.Us
400 Dicas Xp.Erivanildo.Thegenius.Us400 Dicas Xp.Erivanildo.Thegenius.Us
400 Dicas Xp.Erivanildo.Thegenius.Us
 
06 breve histórico do action script - Flash 8
06 breve histórico do action script - Flash 806 breve histórico do action script - Flash 8
06 breve histórico do action script - Flash 8
 
Tratamento de exceções com PHP
Tratamento de exceções com PHPTratamento de exceções com PHP
Tratamento de exceções com PHP
 
C:\Fakepath\Manual Antivirus
C:\Fakepath\Manual AntivirusC:\Fakepath\Manual Antivirus
C:\Fakepath\Manual Antivirus
 
Testes de Software - Módulo 3
Testes de Software - Módulo 3Testes de Software - Módulo 3
Testes de Software - Módulo 3
 
Remover ViluciWare Ransomware
Remover ViluciWare RansomwareRemover ViluciWare Ransomware
Remover ViluciWare Ransomware
 
Apostila matlab
Apostila matlabApostila matlab
Apostila matlab
 
PHPUnit e teste de software
PHPUnit e teste de softwarePHPUnit e teste de software
PHPUnit e teste de software
 
Funções R-statistic
Funções R-statisticFunções R-statistic
Funções R-statistic
 
Simulado da prova lpi 101
Simulado da prova lpi 101Simulado da prova lpi 101
Simulado da prova lpi 101
 
Testes de Software - Módulo 2
Testes de Software - Módulo 2Testes de Software - Módulo 2
Testes de Software - Módulo 2
 
Remover Saved (Scarab) Ransomware
Remover Saved (Scarab) RansomwareRemover Saved (Scarab) Ransomware
Remover Saved (Scarab) Ransomware
 
Remover ArisLocker Ransomware
Remover ArisLocker RansomwareRemover ArisLocker Ransomware
Remover ArisLocker Ransomware
 
Java recursos avançados - multithreading
Java   recursos avançados - multithreadingJava   recursos avançados - multithreading
Java recursos avançados - multithreading
 
Applets
AppletsApplets
Applets
 
Sistemas Operacionais - Aula 07 (Thread e Processos)
Sistemas Operacionais - Aula 07 (Thread e Processos)Sistemas Operacionais - Aula 07 (Thread e Processos)
Sistemas Operacionais - Aula 07 (Thread e Processos)
 
Remover Xati Ransomware
Remover Xati RansomwareRemover Xati Ransomware
Remover Xati Ransomware
 
Testes de unidade e TDD SoLiSC 2011
Testes de unidade e TDD SoLiSC 2011Testes de unidade e TDD SoLiSC 2011
Testes de unidade e TDD SoLiSC 2011
 
Vírus no Linux
Vírus no LinuxVírus no Linux
Vírus no Linux
 

Semelhante a Descobrindo profiling de aplicações java com JProfiler - Getty/IO - Diogenes Ianakiara

Softblue logic-ide
Softblue logic-ideSoftblue logic-ide
Softblue logic-idemateusvini
 
Apostila computacao
Apostila computacaoApostila computacao
Apostila computacaowebphotoshop
 
Aprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalhoAprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalhoFelipeDi
 
Aprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalhoAprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalhoWeldir Fernando Dias
 
Aprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalhoAprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalhoUbirajara Cavaco
 
Silberschatz sistemas operacionais
Silberschatz   sistemas operacionaisSilberschatz   sistemas operacionais
Silberschatz sistemas operacionaisDeryk Sedlak
 
Plano de Projeto de Software para produtos da Lacertae SW
Plano de Projeto de Software para produtos da Lacertae SWPlano de Projeto de Software para produtos da Lacertae SW
Plano de Projeto de Software para produtos da Lacertae SWrafahreis
 
PHP de alta performance com RoadRunner
PHP de alta performance com RoadRunnerPHP de alta performance com RoadRunner
PHP de alta performance com RoadRunnerLeonardo Tumadjian
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1Sliedesharessbarbosa
 
Aula 3 - Formas de Representacao de Algoritmos.pptx
Aula 3 - Formas de Representacao de Algoritmos.pptxAula 3 - Formas de Representacao de Algoritmos.pptx
Aula 3 - Formas de Representacao de Algoritmos.pptxGrsonEgnaciodaConcei
 
3.0018.01.01 manual dicas_tecnicasavancadasdesenvolvimentosoftwareclp
3.0018.01.01 manual dicas_tecnicasavancadasdesenvolvimentosoftwareclp3.0018.01.01 manual dicas_tecnicasavancadasdesenvolvimentosoftwareclp
3.0018.01.01 manual dicas_tecnicasavancadasdesenvolvimentosoftwareclpThiago A. Rondão
 
Apresentacao log
Apresentacao logApresentacao log
Apresentacao logpedrohfsd
 
Manual dicas tecnicasavancadasdesenvolvimentosoftwareclp
Manual dicas tecnicasavancadasdesenvolvimentosoftwareclpManual dicas tecnicasavancadasdesenvolvimentosoftwareclp
Manual dicas tecnicasavancadasdesenvolvimentosoftwareclpUillian Franco
 
Apostila win linux revisada unidade i
Apostila win  linux revisada unidade iApostila win  linux revisada unidade i
Apostila win linux revisada unidade iJosiane Silva
 
Chrome dev tools google io extended 2016
Chrome dev tools   google io extended 2016Chrome dev tools   google io extended 2016
Chrome dev tools google io extended 2016Diego Melo
 

Semelhante a Descobrindo profiling de aplicações java com JProfiler - Getty/IO - Diogenes Ianakiara (20)

Softblue logic-ide
Softblue logic-ideSoftblue logic-ide
Softblue logic-ide
 
Apostila computacao
Apostila computacaoApostila computacao
Apostila computacao
 
Aprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalhoAprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalho
 
Aprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalhoAprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalho
 
Algoritmos com java script
Algoritmos com java scriptAlgoritmos com java script
Algoritmos com java script
 
Debugging node
Debugging nodeDebugging node
Debugging node
 
Aprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalhoAprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalho
 
Silberschatz sistemas operacionais
Silberschatz   sistemas operacionaisSilberschatz   sistemas operacionais
Silberschatz sistemas operacionais
 
Plano de Projeto de Software para produtos da Lacertae SW
Plano de Projeto de Software para produtos da Lacertae SWPlano de Projeto de Software para produtos da Lacertae SW
Plano de Projeto de Software para produtos da Lacertae SW
 
Ficha teorica aula_input_reader
Ficha teorica aula_input_readerFicha teorica aula_input_reader
Ficha teorica aula_input_reader
 
PHP de alta performance com RoadRunner
PHP de alta performance com RoadRunnerPHP de alta performance com RoadRunner
PHP de alta performance com RoadRunner
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1
 
Aula 3 - Formas de Representacao de Algoritmos.pptx
Aula 3 - Formas de Representacao de Algoritmos.pptxAula 3 - Formas de Representacao de Algoritmos.pptx
Aula 3 - Formas de Representacao de Algoritmos.pptx
 
3.0018.01.01 manual dicas_tecnicasavancadasdesenvolvimentosoftwareclp
3.0018.01.01 manual dicas_tecnicasavancadasdesenvolvimentosoftwareclp3.0018.01.01 manual dicas_tecnicasavancadasdesenvolvimentosoftwareclp
3.0018.01.01 manual dicas_tecnicasavancadasdesenvolvimentosoftwareclp
 
Testes de carga com j meter
Testes de carga com j meterTestes de carga com j meter
Testes de carga com j meter
 
Hotpotatoes jn
Hotpotatoes jnHotpotatoes jn
Hotpotatoes jn
 
Apresentacao log
Apresentacao logApresentacao log
Apresentacao log
 
Manual dicas tecnicasavancadasdesenvolvimentosoftwareclp
Manual dicas tecnicasavancadasdesenvolvimentosoftwareclpManual dicas tecnicasavancadasdesenvolvimentosoftwareclp
Manual dicas tecnicasavancadasdesenvolvimentosoftwareclp
 
Apostila win linux revisada unidade i
Apostila win  linux revisada unidade iApostila win  linux revisada unidade i
Apostila win linux revisada unidade i
 
Chrome dev tools google io extended 2016
Chrome dev tools   google io extended 2016Chrome dev tools   google io extended 2016
Chrome dev tools google io extended 2016
 

Descobrindo profiling de aplicações java com JProfiler - Getty/IO - Diogenes Ianakiara

  • 1. a r t i g o Diogenes Buarque Ianakiara (diogenes.buarque@inmetrics.com. br): Está cursando o último semestre de Análise e Desenvolvimento de Sistemas na FIAP. Trabalha com Java desde 2006. Atualmente é analista de desempenho na Inmetrics. Muitas vezes, nos deparamos com problemas de performance nas aplicações quedesenvolvemosourealizamosmanutenções.Amaiorpartedosproblemas está relacionada com a má utilização ou insuficiência de memória. A solução imediata de muitos é aumentar a memória alocada para a aplicação, ou ainda, o número de nós do cluster do servidor de aplicação e finalmente o hardware disponível. Isso tudo sem ao menos realizar uma avaliação prévia do seu comportamento, buscando a causa-raiz dos problemas. Este artigo irá apresentar a técnica de profiling, que visa analisar e identificar problemas de performance em aplicações Java, utilizando a ferramenta JProfiler. 68 www.mundoj.com.br68 Aprenda como encontrar problemas de performance na sua aplicação com o JProfiler. Descobrindo o Profiling de Aplicações Java com JProfiler J ava Profiling é a técnica que visa analisar o desempenho de aplicações coletando métricas e apresentando em tempo real a porcentagem de utilização de threads, carga de objetos e tempo de resposta dos métodos, possibilitando assim a identificação de gargalos e oportunidades de otimização na aplicação. Neste artigo apresentaremos um exemplo de profiling em uma aplicação remota com a ferramenta JProfiler. Vamos desenvolver um EJB simples com três serviços, que simularão um memory leak e um problema de consumo de cpu. Não abordaremos os conceitos de EJB ou padrões de projetos para não fugir do tema. Assim, iremos configurar o ambiente e o servidor de aplicação para que possamos realizar o profiling. Após a instalação, serão apresentadas as principais funcionalidades da ferra-
  • 2. 69 menta e o exemplo de uso de cada uma delas. O JProfiler irá se conectar remotamente à aplicação desenvolvida e iremos por fim realizar a análise e identificar o problema da aplicação. O memory leak, ou vazamento de memória, ocorre quando algum componente da nossa aplicação está utilizando uma determinada quantidade de memória para realizar alguma operação e, após finalizar esta operação, este componente não libera a memória utilizada. Geralmente isto ocorre devido a erros de pro- gramação e pode levar ao consumo total da memória. Instalação e configuração do JProfiler O JProfiler é uma ferramenta paga, porém a ej-technologies, fornecedora da ferramenta, oferece 10 dias de licença Trial, que até a data de escrita deste artigo está na versão 5.2.3. O download pode ser realizado no site http://www.ej-technologies.com/products/jprofiler/overview.html. Configuração 1.1 Uma vez terminada a instalação padrão, a primeira execução apresentará um wizard de inicialização rápida, para configurar o seu primeiro profi- ling. Na primeira tela, selecione a opção de profiling em uma aplicação local ou remota“An application Server, locally or remotely”, como mostra a figura 1. Figura 1. Selecionando o tipo de profiling. Em seguida, será necessário seguir 11 etapas para configurar o profiling. Na figura 2, é apresentada a primeira etapa, escolha o fornecedor e ver- são do servidor de aplicação. Nesse caso, selecione JBoss 5.x. Figura 2. Selecionando o servidor de aplicação. Na segunda etapa, se a aplicação estiver no mesmo servidor em que está instalado o JProfiler, selecione “On this computer”. Caso contrário, selecione a plataforma remota. No nosso caso, selecionaremos “Linux/ AMD64”, como mostra a figura 3. Na terceira etapa, existem três possibilidades: connection from the JProfiler GUI”. Com esta opção, o JProfiler con- figura o servidor de aplicação para que ele aguarde o JProfiler se conectar antes de iniciar. Caso o JProfiler não se conecte, o servidor de aplicação não será inicializado). the JProfiler GUI”, O Jprofiler permite que o servidor inicie normal- mente, possibilitando uma conexão futura com o JProfiler). cannot connect”possibilita a realização do profiling em modo off- line. Com esta opção, é possível configurar o servidor de aplicação para gravar os dados do profiling em um arquivo e assim possibili- tar uma análise off-line). No nosso exemplo, vamos selecionar a opção iniciar imediatamente, conforme a figura 4. Figura 4. Selecionando o tipo de inicialização do Servidor de Aplicação. Agora defina o endereço do servidor remoto, seguindo o exemplo da figura 5. Na quinta etapa, o JProfiler deve ser instalado no servidor. Para isto, existe duas maneiras: 1 – Next, Next, Finish;
  • 3. 2 – Copiar os arquivos de uma instalação préexistente para a mesma versão de SO. O diretório da instalação deve ser informado nessa etapa, como mostra a figura 6. Na sexta etapa, precisamos informar o diretório onde estará o arquivo de configuração de acesso remoto ao JProfiler, e é de extrema importância para o sucesso do profiling. O nome deste arquivo é config.xml e ele será gerado automaticamente ao final deste wizard no diretório “C:Docu- ments and Settings<usuario>.jprofiler5config.xml” para a plataforma Windows e“/home/<usuario>/.jprofiler5/”para a plataforma Linux/Unix. Utilize a figura 7 como referência. É possível observar na figura 8 que agora será necessário acessar o script de inicialização do servidor de aplicação para o JProfiler configurar os pa- râmetros de inicialização necessários. Para esta configuração, compartilhe o diretório do servidor aplicação com as devidas permissões de escrita. Assim, para o JBoss na plataforma Windows acesse o script run.bat no ou run.sh na plataforma Linux/Unix. Após clicar em Next o JProfiler irá gerar um novo script na mesma pasta indicada, chamado run_jprofiler.sh. Figura 8. Acessando o script de inicializar do servidor. No próximo passo, devemos informar fornecedor, versão do Java e o modo de compilação, conforme a figura 9. Como é apresentado na figura 10, o JProfiler utiliza a configuração de- fault, para definir a porta de comunicação. A mesma pode ser alterada caso já esteja em uso. Aqui finalizamos nossa configuração, podemos visualizar as informações sobre este profiling e todos os cuidados que devemos ter antes de iniciar o profiling, como mostra a figura 11. Na 11ª etapa, você pode escolher entre iniciar imediatamente o profiling ou deixar para depois. Figura 11. Finalizando a configuração do profiling. O processo de profiling geralmente é muito oneroso para o processador. Por isso é importante definir um período curto para a execução do profiling. Outro fator importante é o nível de detalhamento do profiling que deve ser definido antes de sua execução, o nível médio é recomendado para CPU e o baixo para memória. Caso seu servidor esteja com folga no uso de memória e CPU, estes níveis podem ser alterados conforme sua necessidade. 70 www.mundoj.com.br
  • 4. Para podermos executar o profiling, vamos desenvolver uma miniaplica- ção que simulará o consumo de CPU e o Memory leak. Construiremos um EJB contendo três serviços. O primeiro serviço simulará um vazamento de memória, o segundo simulará o processamento de uma request sim- ples e, por ultimo, teremos um método que terá a uma maior alocação de memória e processamento, entretanto não possuirá vazamento de memória. Implementação dos serviços 1.1 A Listagem 1 apresenta uma condição de errada no segundo "for", de- vido memory leak que o objeto string tem em cada iteração. Se fosse um registro de um banco de dados, este vazamento poderia resultar em uma falta de resposta da aplicação e esgotar rapidamente da memória disponível. public void memoryLeak(int iter, int count) { for (int i=0; i<iter; i++) { for (int n=0; n<count; n++) { memoryVector.add(Integer.toString(n+i)); } for (int n=count-1; n>0; n--) { memoryVector.removeElementAt(n); } } } public void noMemoryLeak (int size) { HashSet tmpStore = new HashSet(); for (int i=0; i<size; ++i) { String leakingUnit = new String(“Object: “ + i); tmpStore.add(leakingUnit); } } } public void requestMemoryLeak(int iter) { Random requestQueue = new Random(); for (int i=0; i<iter; i++) { int newRequest = requestQueue.nextInt(); pendingRequests.add(new Integer(newRequest)); } } Listagem 1. Implementação do método memoryLeak. Listagem 3. Implementação do método noMemoryLeak. Listagem 2. Implementação do método requestMemoryLeak. A Listagem 2 apresenta um caso muito comum, quando uma requi- sição de entrada é mantida em uma hash table até que a mesma seja concluída, exceto neste exemplo, deixamos de propósito um erro de programação, no qual não removemos do hash table os objetos que foram inseridos anteriormente. Durante um período de tempo, a hash table terá um grande número de alocações, o que resultará em muitas colisões, bem como uma grande parte da pilha ocupada por entradas inúteis. Ambas as listagens são casos muito comuns que resultam em memory leaks. Podemos pensar que os locais de maior alocação de memória são os dois métodos anteriores. No entanto, isso não é verdade. Por exemplo, na Listagem 3, o método noMemoryLeak aloca uma grande quantidade de memória, porém tudo isso é coletado pelo GC (Garbage Collector), deixando a memória sempre disponível. Por outro lado, os outros dois métodos que não alocam muita memória estão causando constante- mente memory leaks. Realizando o profiling e identificando o problema Primeiramente vamos abrir o JProfiler e selecionar a opção“Start Center”. Dentre as opções disponíveis, selecione a opção que você configurou no primeiro tópico, e clique em Start. Conforme a figura 12. Figura 12. Selecionando a o profiling configurado. O wizard apresentado na figura 13 dá a possibilidade de configurar os níveis de detalhamento do profiling, iremos utilizar os níveis recomen- dados para não degradar o ambiente testado. Clique em ok para iniciar o profiling. Agora vamos iniciar nossa aplicação cliente, que por sua vez consumirá os serviços do nosso componente MemoryLeakEJB. A Listagem 4 apre- senta o código que simulará a utilização dos serviços disponíveis. Inicie a aplicação cliente. 7171
  • 5. public static void main(String[] args) { Properties properties = new Properties(); properties.put(“java.naming.factory.initial”,”org.jnp.interfaces. NamingContextFactory”); properties.put(“java.naming.factory.url.pkgs”,”= org.jboss.naming:org.jnp.interfaces”); properties.put(“java.naming.provider.url”,”10.10.11.97:1099”); try { Context context = new InitialContext(properties); MemoryLeakRemote memoryLeakRemote = (MemoryLeakRemote) context.lookup(MemoryLeakBean. RemoteJNDIName); for (int i=0; true; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(“iteração nº: “ + i); memoryLeakRemote.slowlyLeakingVector(1000,10); memoryLeakRemote.leakingRequestLog(5000); memoryLeakRemote.noLeak(100000); } } catch (NamingException e) { e.printStackTrace(); throw new RuntimeException(e); } } Listagem 4. Implementação de uma aplicação Cliente. Identificando problemas de vazamento de memória Neste momento, o JProfiler está conectado com o nosso servidor de aplicação. A primeira métrica que o JProfiler nos apresenta é a“Memory Views”. Estes dados dão a possibilidade de visualizar os níveis de agre- gação, podemos selecionar os níveis Class, Packages, J2EE Components. Para nosso exemplo, selecionaremos J2EE Components. Esta opção apre- senta os componentes JEE mais utilizados no App Server, geralmente ele também apresenta componentes do próprio servidor de aplicação, porém podemos observar na figura 14 que dentre eles encontramos o nosso componente“MemoryLeakBean”. Figura 14. Visualizando métricas de memória da Aba All Objects. As abas da parte inferior nos apresentam métricas diversificadas do uso de memória no servidor de aplicação. Ao selecionar uma aba, será apre- sentado um botão ao qual será possível iniciar o monitoramento que desejamos. Para nosso exemplo, vamos utilizar apenas as aba inicial, All Objects e Allocation Call Tree. O ideal é avaliar um item por vez, seja ele memória, CPU, threads, ou snapshots. Para não degradar totalmente o ambiente. Uma que você iniciou uma avaliação é impor- tante armazenar todas as evidências do que foi analisado, para futuras comparações, como também para um históri- co do comportamento da aplicação. Após identificar que o componente MemoryLeakBean está na lista de objetos da aba All Objects, selecione a aba Allocation Call Tree. Esta aba apresentará uma árvore de utilização da memória. Como podemos observar na imagem da figura 15, os métodos do componente MemoryLeakBean consomem aproximadamente 50% do tempo de uso e alocação de memória, especialmente o método noLeak. AgoravamosselecionaraopçãoVMTelemetryViews.Estaopçãoapresen- tará gráficos de utilização da Heap, Thread e até CPU load. Ao selecionar pela primeira vez esta opção, já podemos observar um comportamento incomum da Heap. Notamos na figura 16 que este comportamento re- presenta um memory leak ou vazamento de memória. Indo mais a fundo, vamos selecionar a aba GC Activity, que nos apresen- tará um gráfico da atividade do Garbage Collector. Podemos notar na fi- gura 17 uma intensa atividade de GC, este comportamento se dá quando possuímos muitos novos objetos alocados, preenchendo todo espaço da Heap. Caso não haja mais memória para alocação, será lançado o“velho e conhecido”erro java.lang.OutOfMemory. 72 www.mundoj.com.br
  • 6. Figura 17. Visualizando o gráfico de atividade do GC. Identificando problemas de consumo de CPU A opção CPU Views apresenta detalhadamente a árvore de uso de CPU. Podemos observar na figura 18 que 95% da utilização de CPU está alo- cada nos três métodos que estamos consumindo. Podemos filtrar ainda mais utilizando a opção Thread status. Esta opção fornece a visualização detalhada do uso de classes e métodos por estado de cada thread, seja ele blocked, running ou waiting. Figura 18. Visualizando a árvore de consumo de CPU. As abas Hot Spots apresentam tanto para memória ou CPU pontos que possivelmente podem ser críticos, porém estas métricas requerem um maior nível de detalhamento do profiling. Muitas vezes estas métricas podem apresentar resultados genéricos, como java.lang.String ou java. lang.Integer, entretanto, se você possuir um método muito oneroso para o sistema, ele com certeza aparecerá nesta análise. Como podemos ob- servar o método noLeak da figura 19. Figura 19. Visualizando possíveis pontos de interesse. Após identificar as causas de um problema de performance, deve-se ana- lisar profundamente o problema para se obter a melhor solução. Muitas vezes estes problemas podem ser resolvidos com otimizações do código, porém nem sempre podemos alterar o mesmo, por exemplo, quando o código não nos pertence. Outros problemas podem ser resolvidos com o tuning da JVM. Tuning da JVM é o ato de otimizar o uso do garbage collector para que ele seja executado de forma mais efi- ciente, possibilitando assim um ganho de performance na aplicação. Não está no escopo do artigo se aprofundar em como resolver os pro- blemas de performance ou como desenvolver um EJB. Todos os códigos estarão disponíveis no site http://www.mundoj.com.br. Sabermais Na edição 35 da revista Mundoj o artigo “Co- nhecendo os parâmetros de configuração mais utilizadosdaJVM”apresentoutécnicasdecomo otimizaraJVM. Considerações finais Neste artigo foi apresentadas algumas formas de identificar problemas de performance em aplicações Java utilizando a técnica de profiling. Esta técnica está fortemente ligada ao ciclo de vida das aplicações, uma vez que uma aplicação já nasce com problemas de performance, certamente estes problemas só irão aumentar. Assim buscamos apresentar não só os conceitos do profiling, mas também um exemplo prático de como iden- tificar esses problemas. No primeiro tópico apresentamos como configurar a ferramenta e cons- truir um profiler remoto, seguindo, construímos duas aplicações, um EJB que simulou problemas de memory leak e cpu load e uma aplica- ção cliente que por sua vez consumiu todos os serviços do EJB. Assim, aprendemos como iniciar um profiling visualizando métricas de memória e cpu e como identificar não só o componente, mas também a classe e os métodos que apresentavam os problemas de performance. É importante salientar que apenas identificando o gargalo não necessariamente o problema estará resolvido. É preciso analisar e evidenciar para se chegar Referências 7373