Segunda-feira, 5 Abril 2010

Análise e melhoria de um teste com GC

Motivado pela liberação do teste de threads, quiz fazer um pequeno teste, que ajude a analisar o funcionamento do Garbage Collector e como algumas alterações podem melhorar o desempenho.

Quando se fala em teste, existe muita discussão sobre a validade dos resultados.

Então já digo que este é um teste caseiro, para ter sua opinião, faça o teste em seu ambiente.

1) Teste

O teste de threads (NumThreads.java, projeto completo), lança todas as threads enumeradas no parametro, em que cada thread faz uma série de processamento matemático, cada thread pode repetir o processamento em uma quantidade determinada.

o fluxo de criaçao, coloca em um array, depois faz o start de cada thread, depois faz um join para esperar o processamento de todas as threads.

O start de cada thread não começa imediatamente, existe um barreira (CyclicBarrier) que aguarda o contador de todas as threads que foram iniciadas para que todas possam de fato entrar em operação juntas.

Em uma configuração default da JVM não consegui inicar com mais de 2700 threads, 2000 operações matemáticas por thread, ocorriam erros da JVM (OOME, ThreadDeath, Stackoverflow, etc.)

A minha máquina é um laptop toshiba, Core2 Duo T2400 1.83 GHz com 3 GB de RAM.

2) Monitoramento

O monitoramento foi feito usando o vmstat, jvisualvm, jmap
No caso do vmstat, coloquei a data como prefixo.

3) Resultado (1a bateria)

O teste foi iniciado com os seguintes parametros, que geralmente é o comum, onde configura-se apenas o tamanho máximo do heap. Depoi veremos o que se pode melhorar neste teste.

$ time java -Xmx2g -classpath build/WEB-INF/classes/:src/conf/:src/java/ br.com.claudius.threads.NumThreads 2700 5000 60

O tempo total, deve ser descontado 60s que usei como pausa antes das threads começarem de fato (3o parametro)

real 3m11.948s
user 2m14.612s
sys 1m40.354s

O tempo total foi de 2min11s ou 131s O que chama a atenção na configuração default é o tamanho do Stack de 320 kb, bem grande.

$ jinfo -flag ThreadStackSize 18610
-XX:ThreadStackSize=320

A configuração do heap (apenas a parte importante)

$ jmap -heap 18610
Server compiler detected.
JVM version is 16.0-b13

using thread-local object allocation.
Parallel GC with 2 thread(s)

Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 2147483648 (2048.0MB)
NewSize = 4194304 (4.0MB)
MaxNewSize = 4294901760 (4095.9375MB)
OldSize = 4194304 (4.0MB)
NewRatio = 2
SurvivorRatio = 8
PermSize = 16777216 (16.0MB)
MaxPermSize = 67108864 (64.0MB)

Um pedaço do vmstat durante a execução

2010-04-02 20:47:16 procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
2010-04-02 20:47:16 r b swpd free buff cache si so bi bo in cs us sy id wa
...
2010-04-02 20:48:44 51 0 0 283440 81520 1825480 0 0 0 0 1131 934 61 36 3 0
2010-04-02 20:48:48 50 0 0 286032 81528 1811856 0 0 0 11 1230 1291 64 30 5 0
2010-04-02 20:48:52 109 0 0 259780 81528 1811324 0 0 0 5 1133 1579 58 36 5 0

Percebe-se que a "run queue" (coluna r) possui um alto número de tarefas aguardando um tempinho da CPU para processar alguma instrução.

Vejam um screenshot do visualgc ao fim do teste


<info>

O VisualGC é um plugin do VisualVM. Na versão atual do Java, o visualvm faz parte do download do java, mas é chamado de jvisualvm.

Durante o teste ocorreram 115 ações do GC na área YOUNG que duraram 3.306 ms, enquanto a área OLD com seus 1,3 GB ociosos.


VisualGC 1

4) Análise

O objetivo do teste é a JVM e não a aplicação, então nem vamos olhar na aplicação.

Sempre em uma análise do GC, é importante diminuir o impacto do tempo do GC na aplicação. Sempre que puder diminuir o tempo total do GC ajuda o throughput da aplicação.

Em uma análise óbvia, percebe-se que a área OLD está ociosa, enquanto existe atividade intensa na área YOUNG, então seria natural aumentar a área YOUNG para um tamanho grande. Aqui que costuma ocorrer um erro comum também, onde aumentar uma área é proporcional ao tempo de GC, pelo tamanho maior a ser varrido.

Por esta applicação ser orientada a CPU (muitas threads), processamento matemático, sem sincronização, sem rede, sem banco de dados, então é uma análise orientada para menor consumo de CPU e otimização do funcionamento do Garbage Collector.


5) Resultado (2a bateria)

Será feito uma otimização na invocação do comando java

$ time java -server -XX:+AlwaysTenure -XX:+UseConcMarkSweepGC -Xss64k -Xms2g -Xmx2g -classpath build/WEB-INF/classes/:src/conf/:src/java/ br.com.claudius.threads.NumThreads 2700 2000 10
Parametros adicionais:

Parametro
Explicação
-server Usa otimizações específicas para o modo de aplicações servidoras.
-XX:+AlwaysTenure Não usa espaços Survivors da área YOUNG, a promoção vai direto da YOUNG para OLD.
-XX:+UseConcMarkSweepGC Usa o algoritmo concorrente na área OLD e Paralelo na área YOUNG (-XX:+UseParNewGC)
-Xss64k Reserva 64 kb para o tamanho do stack de thread.
-Xms2g Aloca inicialmente o tamanho do heap para 2 GB
     
real 1m5.618s
user 0m51.967s
sys 0m38.598s

Percebe-se a melhoria no tempo de 66s.

Descontar 10s deste tempo final, pois na aplicação tem uma pausa de 10s antes de começar o teste.

O visualgc mostra uma melhoria significativa, onde ocorreram 86 ações do GC com duração da atividade de  GC em 836 ms.

VisualGC 2

Ao efetuar a mesma medição com o jstat, percebe-se uma melhoria marginal no tempo total do GC, mas com boa diminuição na quantidade de GC.

$ jstat -gcutil 1451 3s
S0 S1 E O P YGC YGCT FGC FGCT GCT
0,00 0,00 54,22 0,08 11,30 71 0,799 0 0,000 0,799
0,00 0,00 81,01 0,08 11,30 75 0,808 0 0,000 0,808
Ao diminuir o tamanho do stack para 48k (o mínimo aceito pela JVM), o tempo do GC melhorou bem.
Com -Xss48k
$ jstat -gcutil 4265 3s
S0 S1 E O P YGC YGCT FGC FGCT GCT
0,00 0,00 44,52 0,08 11,30 75 0,670 0 0,000 0,670
0,00 0,00 97,33 0,08 11,30 79 0,685 0 0,000 0,685

O comportamente da CPU mostrado pelo vmstat, mostra um uso bem mais modesto da CPU, veja a coluna r (run queue)

2010-04-05 00:40:14 procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
2010-04-05 00:40:14 r b swpd free buff cache si so bi bo in cs us sy id wa
...
2010-04-05 00:40:53 24 0 0 1386056 249416 953668 0 0 0 0 1190 631 52 32 16 0
2010-04-05 00:40:56 7 0 0 1390532 249424 953660 0 0 0 4 1199 645 59 32 10 0
2010-04-05 00:40:59 18 0 0 1395652 249424 953500 0 0 0 0 1196 609 54 34 12 0

Nota 2: o VisualGC é um plugin do VisualVM (Tools -> Plugins -> Available Plugins)

5) Conclusão

No 2o teste foi percebido uma melhoria significativa no tempo total e com menos impacto na utilização da CPU.

Não foi feito um super mega tunning para este exemplo, mas mostrar que com uma boa análise, alguns testes, é possível observar o comportamento da aplicação e aplicar as otimizações no lugar certo.

Tente executar um teste e análise em seu ambiente.

6) FAQ ?

6.1) Você usou o G1 ?

Usei o algorítimo G1 mas o resultado foi inferior ao concorrente, mas o pior neste caso foi que a ferramenta jstat não consegue exibir os resultados das áreas de memória.

Warning: Unresolved Symbol: sun.gc.generation.0.space.1.capacity substituted NaN
Warning: Unresolved Symbol: sun.gc.generation.0.space.1.used substituted NaN
...
Warning: Unresolved Symbol: sun.gc.collector.0.time substituted NaN
Warning: Unresolved Symbol: sun.gc.collector.1.time substituted NaN
S0 S1 E O P YGC YGCT FGC FGCT GCT
� � � � 30,33 � � � � �

6.2) Porque aumentar o stack size da aplicação de teste para monitorar ?

Parece que as ferramentas gráficas jconsole e visualvm exigem um stack de tamanho maior para monitorar, caso contrário ocorre um erro

*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 806
Segmentation fault

isso é assunto para outro blog

6.3) Porque não aumentar o tamanho da área YOUNG (-XX:+NewSize)

Ao aumentar o tamanho da área YOUNG diminuiu a quantidade de GC, mas o tempo total do GC aumentou e isso trouxe uma performance inferior ao teste final. Nem sempre aumentar o tamanho da YOUNG beneficia a aplicação. Cada caso tem de ser analisado diferente.

Escrito por claudio at 11:23 AM categorizado por Java

Tags: java performance

Quinta-feira, 2 Outubro 2008

Geração de heap dump no linux 64 bits

Estou em um trabalho para um cliente envolvendo melhorias de performance na aplicação e no ambiente operacional (appserver, sistema operacional, jvm).

O ambiente é Linux 64 bits (RedHat, kernel 2.6.18 SMP), JDK 5 e Glassfish v2 ur2.

Em um dado momento, precisei gerar um heap dump, mas ocorreu um erro  sun.jvm.hotspot.debugger.UnmappedAddressException.

# /usr/local/jdk/jdk1.6.0_07/bin/jmap -J-d64 -F -dump:file=java_dump_10791.hprof  10791
Attaching to process ID 10791, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 10.0-b23
Dumping heap to java_dump_10791.hprof ...
Exception in thread "main" java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at sun.tools.jmap.JMap.runTool(JMap.java:178)
        at sun.tools.jmap.JMap.main(JMap.java:110)
Caused by: sun.jvm.hotspot.debugger.UnmappedAddressException
        at sun.jvm.hotspot.debugger.PageCache.checkPage(PageCache.java:208)
        at sun.jvm.hotspot.debugger.PageCache.getData(PageCache.java:63)
        at sun.jvm.hotspot.debugger.DebuggerBase.readBytes(DebuggerBase.java:205)
        at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.readCInteger(LinuxDebuggerLocal.java:471)
        at sun.jvm.hotspot.debugger.DebuggerBase.readAddressValue(DebuggerBase.java:442)
        at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.readOopHandle(LinuxDebuggerLocal.java:431)
        at sun.jvm.hotspot.debugger.linux.LinuxAddress.getOopHandleAt(LinuxAddress.java:115)
        at sun.jvm.hotspot.oops.Oop.getKlassForOopHandle(Oop.java:222)
        at sun.jvm.hotspot.oops.ObjectHeap.newOop(ObjectHeap.java:348)
        at sun.jvm.hotspot.utilities.HashtableEntry.literal(HashtableEntry.java:53)
        at sun.jvm.hotspot.memory.SymbolTable.symbolsDo(SymbolTable.java:106)
        at sun.jvm.hotspot.utilities.HeapHprofBinWriter.writeSymbols(HeapHprofBinWriter.java:830)
        at sun.jvm.hotspot.utilities.HeapHprofBinWriter.write(HeapHprofBinWriter.java:396)
        at sun.jvm.hotspot.tools.HeapDumper.run(HeapDumper.java:56)
        at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)
        at sun.jvm.hotspot.tools.HeapDumper.main(HeapDumper.java:77)

Tentei gerar o dump através de:

  • -XX:+HeapDumpOnCtrlBreak and kill -3
  • jmap -heap:format=b
  • gcore utility

Com isso decidi usar o JDK 6 u7 (changelog), mas ocorreu o mesmo problema.

UPDATE: A stacktrace mostrada acima, mostra a invocação de um comando jmap do JDK 6 u7, para uma VM 6 u7.
UPDATE: Anteriormente, quando estava com JDK 5 u12, tentei rodar o jmap a partir de uma VM 5 u12, mas o mesmo erro ocorreu
UPDATE: A VM não está com a opção -Xrs option.
UPDATE: O usuário que iniciou o processo é o mesmo que usei para invocar o comando jmap, root.

UPDATE: Alan Bateman, explicou sobre o uso da opção -F "A opção -F faz como que a ferramenta se conecte no processo de uma maneira não colaborativa e pode causa a geração de um dump inconsistente. Em outras palavras, não há garantia de que será um bom heap dump ao usar a opção -F", veja este comentário em inglês na seção de comentários abaixo.

Então encontrei um bug corrigido "Throws UnmappedAddressException while reading address from core file in shared area.", entao decidi usar o JDK 6 u10 RC.

Coloquei a opção -Xshare:off

E funcionou muito bem,o processo não foi derrubado e a aplicação funcionou normalmente.

Não esqueça que no momento do heap a JVM paralisa todas as threads e o arquivo gerado será tão grande (ou um pouco menor) como a memória RSS usada pelo processo.

Então, se for gerar heap dump em linux 64 bits, use o JDK 6 u10 RC com a opção -Xshare:off.

Ao final da geração do heap dump, as mensagens abaixo foram impressas

"Finding object size using Printezis bits and skipping over..."

Obrigado Tony, pelo seu trabalho no HotSpot.

Escrito por claudio at 1:28 AM categorizado por Java

Tags: java performance linux

Terça-feira, 9 Setembro 2008

Ferramentas de diagnóstico em performance na prática

3

Tenho efetuado a palestra sobre diagnóstico em problemas de performance, desde 2006 em diversos eventos.

Pelo feedback que recebo, percebo que este é um assunto de interesse para um numeroso grupo de profissionais.

Então, é por isso que você que é interessado em entender mais sobre performance, garbage collector, thread pools, thread dumps e memory dumps, deve comparecer no próximo dia 12 (sexta-feira) as 9h no Senac, onde ocorre o JustJava. Pois irei realizar um workshop na prática sobre este assunto.

O nome é "Diagnóstico e Resolução de Problemas de Performance em Java", é requerido trazer o laptop para máximo aproveitamento.

O workshop (hands-on lab), será um misto de palestra com exercícios sobre o tema. Será seguido (tentativa) o seguinte roteiro:

  • Explicação sobre um tópico
  • Demonstração
  • Fazer com que os atendentes resolvem um exercício

Os tópicos serão

  • Gerenciamento de memória do Java
  • Ferramentas para diagnóstico
  • Thread Dumps
  • Memory Dumps
  • Ferramentas para profiling

Para um máximo rendimento para o atendente, é necessário seguir alguns pontos:

Configurem as variáveis JAVA_HOME e PATH=$JAVA_HOME/bin

O uso do Linux não é obrigatório, mas facilita muito, e irei basear meus exemplos nele.

Note, que o tempo do workshop não será prejudicado, por aqueles que não possuem os sistemas instalados. Pois o tempo é curto para muito conteúdo de não fácil absorção.

Não posso esperar pela próxima sexta, para divertir com thread dumps, pools estourando e memória escorrendo pelos buracos do laptop.

Escrito por claudio at 2:57 AM categorizado por Java

Tags: eventos java noticias palestra justjava performance

Quinta-feira, 21 Agosto 2008

HotSpot Internals

Encontrei um tempo atrás, um site wiki no endereço da Sun.com com informações interessantes para quem quer entender mais sobre HotSpot, mas não tem tempo para ler o código fonte, é o HotSpot Internals.

Como exemplo cito uma página sobre otimizações em código java, onde o HotSpot consegue tirar melhor proveito.

Escrito por claudio at 12:55 AM categorizado por Java

Tags: dicas java performance

Quarta-feira, 25 Junho 2008

Acontecimentos no Jazoon 2008

Estou em Zurich para o evento Jazoon, desde domingo, apreciando a cidade e o evento que começou com o Community Day na segunda-feira, onde participei da parte do Glassfish, enquanto a outra parte era dedicada ao NetBeans. Devo dizer que a organização do evento está muito boa.

Tenho encontrado alguns brasileiros que vieram participar do evento, bem como outros que moram na região. Notadamente o Felipe Gaúcho, onde o pude conhecer pessoalmente onde fez um tour da cidade comigo, muito obrigado. Também explicou como é trabalhar para o mercado Suiço e o choque cultural, é uma experiência muito interessante.

Fiz minha palestra ontem, a sala começou em torno de 20 pessoas, mas ao final devia ter algo em torno de 50 pessoas. Foi muito bom participar do evento, principalmente quando temos membros ilustres na audiência como Dr. Heinz Kabutz, Alexis Mouchine-Pouchkine (evangelista Sun/Glassfish).

O slide da palestra está disponível, vejam on-line ou façam download.

Antes de minha palestra, outro brasileiro fez palestra sobre The Java Platform and the future of user interaction, por Hildeberto Mendonça que faz doutorado na Bélgica.

Posteriormente conversei com Heinz Kabutz, sobre as ferramenas de análise de thread dump para detecção de conteção. Conversei com Alexis sobre a comunidade Glassfish no Brasil, onde temos muita oportunidade para mostrar a qualidade do projeto. Com Jerome Dochez comentei sobre alguns problemas encontrados no Glassfish v3 (em desenvolvimento), sobre logging, reload de módulos e build do glassfish v3 (posteriormente coloco os detalhes destas questões).

Anteriormente conversei com Terrence Barr, sobre um problema que enfrentei ano passado com certificaçao digital e Java Micro Edition, onde ele compartilhou do problema e que a Sun está tentando mostrar às empresas operadoras e fabricantes, sobre a importância da padronização em API e acesso a recursos nativos.

Hoje pela manhã assisti a palestra Web 2.0 development with JavaFx, Flex and AIR, muito interessante, pois eu já conhecia o site do parleys.com, e o Stephan Janssen, mostrou as motivações de ter escolhido a plataforma Adobe Flex para construir a UI do site. Em off conversando com ele, mostrou que ainda existem algumas marretadas a serem ajustadas para tornar aplicações Flex usáveis para usuários acostumados com HTML, como por exemplo indexação por robôs web (é necessário adicionar keywords no header), pesquisa por ctrl+f no browser, link direto em ancora. A interface visual do site é bem interativa e bonita. Ele também mostrou outras funcionalidades do site, onde será aberto para usuários realizarem uploads de vídeos, bem como usar uma ferramenta criada por ele para editar e sincronizar slides de palestras com áudio ou video. Isso é muito bacana, para quem não pode estar presente à um evento, e pode assistir fora do evento.

Uma palestra que estava com intenção de assistir, sobre Qi4j sobre um novo conceito em desenvolvimento de software, projeto liderado pelo Rickard Öberg, foi cancelada, não sei o motivo. Isso irá me forçar a assinar as listas de discussão deles para aprender mais sobre o projeto.

Em conversas com outras pessoas técnicas de países diferentes, verifiquei que compartilhamos algumas coisas em desenvolvimento de software, como o cliente não conseguir mostrar quais são os casos de uso mais importantes, efetuar testes funcionais quando a aplicação vai para produção, não terem requerimentos de performance, baixa qualidade do código desenvolvido em off-shore, conservadorismo no uso do software em produção.

Vejam algumas fotos (cidade de Zurich e parte do evento).

Escrito por claudio at 11:37 AM categorizado por Java

Tags: eventos java noticias jazoon performance

Sexta-feira, 13 Junho 2008

Palestra no Jazoon

Jazoon 2008

Na semana do dia 23, irei participar do evento Jazoon, com a palestra Tools and Tips to Diagnose Performance Issues, essa palestra é uma reformulação de outras que fiz em eventos anteriores.

Existe uma caravana de brasileiros que irá participar do evento, entre eles o Felipe Gaúcho que mora na cidade onde irá ocorrer o evento. Será uma boa semana, interagir com membros da comunidade Java internacional, entender o que é diferente na cultura de TI, entre outras coisas e conhecer Zurich.

Muito bacana participar deste evento, pois é o 2o Jazoon, e já é considerado um evento com muita qualidade, veja a lista dos palestrantes e palestras neste ano.

Muitas palestras de qualidade para assistir, compartilhar conhecimento, aprender, tanto do lado técnico como do lado cultural. 

Algo que achei muito interessante, é que o evento é realizado em um cinema, com uma tela gigante onde será projetado os slides. Veja algumas fotos do evento em 2007. Acredito não ser necessário reduzir o tamanho da fonte do console na demonstração (ROFL)



Mesmo se você não puder ir a Zurich assistir a palestra, pode ser preparar e ir ao evento WebDays que irá ocorrer em São Paulo no dia 22 e 23 de agosto. Onde vou apresentar essa palestra, mas em português.

Irei apresentar outra palestra, sobre produtividade na web com Wicket. Isso mesmo, Wicket !

Pois bem, eu já havia lido e feito alguns exemplos com este framework em 2006, mas não achei interessante (na época) o conceito dele de separação do HTML e código Java. Mas depois de trocar algumas informações com o Bruno Borges, percebi que o framework é bem rico em componentes, possibilita uma simplicidade incrível, não é necessário uma IDE com suporte completo ao framework, pois é necessário apenas HTML (XHTML para ser exato) e Java. Se quiser saber mais, vai ter de assistir a palestra, com direito a demonstração.

Escrito por claudio at 11:27 AM categorizado por Java

Tags: eventos java noticias palestra performance

Sexta-feira, 4 Abril 2008

Palestras em 2008, eventos marcados

A temporada de eventos já começou e tenho marcado palestras em alguns eventos.

Jazoon 2008

Um evento anual em Zurique, Suiça. Tenho a palestra "Tools and Tips to Diagnose Performance Issues", marcada para o dia 24 de Junho. Veja a programação completa de palestras e horários.

Esta palestra tem sido melhorada desde os últimos eventos, e as pessoas que assistem dizem foi de boa utilidade em seus ambientes de trabalho. Tanto em emails que recebi como discussões em fórums e blogs na internet.

Olhando a lista de palestrantes, mostra que é um evento que mostra muita credibilidade, e vai permitir muita troca de informação.

Este evento é um dos maiores da europa, sobre a tecnologia Java. Vejam as fotos e fatos do evento em 2007, que informa muita coisa interessante.

FISL 9 - Forum Internacional de Software Livre

Esta será a 3 vez que participo do FISL (outras foram em 2004 e 2007), e o evento já é reconhecido como um dos maiores eventos do mundo no segmento de TI e Open Source.

Irei participar com a palestra "Produtividade na Web com Apache Wicket", marcada para o dia 19 de Abril. O que achei interessante é o nome das salas, a qual vou ocupar chama-se Tim Berners Lee, quanta honra.

Você pode ver a programação completa de palestras e horários

De fato esta palestra, assim como várias outras são organizadas dentro do evento Javali, que acontece desde 2004, que é um evento dedicado a tecnologia Java e organizado pelo SouJava. Veja a programação de palestras para o Javali.

Podem esperar fotos e blogs sobre estes eventos, pois tem muita coisa interessante.

Escrito por claudio at 7:07 PM categorizado por Java

Tags: eventos fisl java javali noticias palestra performance

Quarta-feira, 20 Fevereiro 2008

Resolvendo memory leak - Identificando o comedor de memória

Resolvendo memory leak - Procurando o devorador de memória - parte 1


Algo que vejo recorrente em fóruns e listas de discussão, colegas que perguntam para mim, é "como detectar e resolver o memory leak ?"

Começarei uma série de dicas voltados a encontrar e resolver o problema de retenção de memória (memory leak) em aplicações Java. Posteriomente, será feito um tutorial para resolver problemas de CPU.

Estas dicas podem ser úteis para programadores que ainda não passaram por este problema ou não conhecem as ferramentas. Mesmo para profissionais experientes, espero que possa contribuir.

Isso é baseado em minha experiência, em ambiente linux e solaris. Será dado ênfase no uso de ferramentas gratuitas ou de código livre, para ajudar neste processo. Para ambiente windows, onde possível colocarei as dicas aplicáveis para este SO, mas devo dizer que não tenho especialidade neste SO, portanto desconheço as ferramentas mais adequadas.

Ambiente de produção e desenvolvimento

Também será mostrado como resolver esse problema, tanto em ambiente de produção como em ambiente de desenvolvimento, com as ferramentas disponíveis em cada amviente (exemplo: invocar profiler ou debug em ambiente de produção é bastante caro em termos de performance).

É importante endender que a aplicação pode sofrer monitoramento de maneira intrusiva e não intrusiva.

  • Intrusivo: quando é necessário modificar as configurações de inicialização da aplicação para permitir uma introspecção de suas chamadas de sistemas e quando ocorre uma interceptação destas chamadas de sistemas pelo esquema de monitoramento intrusivo. Um exemplo disso são os profilers e debuggers. Isso gera penalidade em performance, modificação da configuração do ambiente e instalação de ferramentas, o que em ambiente de produção pode ser um grande problema
  • Não intrusivo: Quando é usado ferramentas de monitoramento, que não geram interceptação das chamadas do sistema, não geram impacto negativo em desempenho e não precisam de instalação de software adicional.

Existem uma série de passos, começando por descobrir onde ocorre problema de retenção, até sua resoluçao.

Qual processo do sistema operacional consome memória em demasiado ?


Este é o 1o passo, para identificar se o programa (desktop ou servidor) consome memória sem manter estável.

É importante entender que a aplicação deve ter passado por todas as etapas de criação de objetos e recursos, que já tenha passado por um ciclo de vida. Isso pode ser alcançado, navegando pela aplicação, consultando relatórios, etc.

É necessário usar apenas o SO e suas ferramentas, para descobir qual o processo está neste estado.

Ferramentas:

  • Linux: top, htop, ps
  • Solaris: prstat, ps
  • Windows: gerenciador de tarefas

Segue um exemplo de um programa que consome memória (propositadamente), e sua medição pelos respectivos utilitários do SO.

Vejam que existe um processo java que consome muita memória. O que neste caso interessa saber o PID (process ID) e a linha de comando.

Linux top

Percebe-se uma visualização com cores, linha de comando completa e ordenação diferentes, isso pode ser alcançado por atalhos

z => modifica o esquema de cores

c => mostra a linha de comando completa

shit M => ordena pelo consumo de memória

W => Torna esta configuração o padrão nas próximas invocações do comando top

O top tem uma vantagem, que ele já vem instalado em qualquer linux, então não é necessário efetuar download e instalá-lo. Já o htop, fornece uma visualização melhorada, mas é necessário efetuar download e instalar.

Para saber o consumo da memória por processo, veja na coluna RSS (ou RES), este é o valor de memória física consumido pelo processo (de fato, existem algumas discussões em fórums sobre o comando RSS ser bem uma aproximação do valor real, mas fico devendo uma explicação melhorada sobre isso em outro blog)

Linux htop

Este utilitário, fornece uma visualização melhorada sobre os processos e os recursos.

Linux ps

$ ps -eo pid,user,%cpu,rss,vsz,etime,nlwp,args
  PID USER     %CPU   RSS    VSZ     ELAPSED NLWP COMMAND
 7642 claudio   0.7 343536 658804      05:23   12 java TestReferences

A diferença do comando ps e top, é apenas a visualização, já que o ps recupera um snapshot do sistema.

O diferencial deste comando, é que mostra também a quantidade de threads por processo, na coluna NLWP.

Solaris prstat

$ prstat -s rss
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
   617 claudio   102M   78M sleep   59    0   0:00:01 2.1% java/9
   554 root      106M   32M sleep   59    0   0:00:01 0.2% ns-httpd/71
     7 root       11M   10M sleep   59    0   0:00:03 0.0% svc.startd/12
     9 root       11M 9384K sleep   59    0   0:00:07 0.0% svc.configd/17
   308 root       12M 8528K sleep   59    0   0:00:01 0.0% fmd/16
   553 root       27M 8088K sleep   59    0   0:00:00 0.0% ns-httpd/2
   618 root     8936K 4416K sleep   59    0   0:00:00 0.0% sshd/1

Foi usada a opção prstat -s rss para ordenar a apresentação baseada no consumo de memória. Outra informação é a quantidade de threads por processo, na coluna NLWP

Windows task manager


Então foi identificado qual é o sistema que consome mais memória. Com isso é possível ter um ponto de partida na análise do processo.

No próximo blog, que pretendo escrever em dois dias (espero), será mostrado como detectar se existe memory leak.

Escrito por claudio at 12:45 AM categorizado por Java

Tags: dicas java linux performance solaris

Quarta-feira, 14 Novembro 2007

Palestra "Performance em Aplicações Java" disponível

A palestra que ministrei no evento Conexão Java 2007 está disponível para download. Ou você pode assistir on-line à apresentação.

Nesta palestra coloquei mais algumas dicas de performance em Java, bem como houve uma sessão de QA ao final.

Quero agradecer à organização do evento pela oportunidade e à galera que aguentou firme 1,5h de assunto um tanto pesado.

Escrito por claudio at 5:20 AM categorizado por Java

Tags: java noticias palestra performance

Sábado, 10 Novembro 2007

450 GB de HEAP

Conversei com alguns colegas sobre um artigo que li há um tempo, onde mostrava que o BEA JRockit foi usado em um heap da ordem de terabytes.

Pois eu confundi, e o heap é de 450 GB. Vejam o artigo

Escrito por claudio at 8:14 PM categorizado por Java

Tags: java performance

Quarta-feira, 24 Outubro 2007

Conexão Java 2007 - Palestra sobre performance

Conexão Java 2007, eu vou !

Já percebi outros blogueiros comentando sobre o Conexão Java 2007, próximo dia 09 de novembro em São Paulo. Então eu já estava atrasado para escrever sobre isso.

Recebi um convite para efetuar uma palestra sobre Performance de Aplicações Java, e aceitei com honra participar de tal evento que conta com prestígio da comunidade Java.

Performance é um tema bastante abrangente, e como tenho uma certa atração por esta área, então tenho muitas horas para conversar e explicar sobre esse tema, cobrindo, análise, ferramentas, técnicas, ambientes, código e infraestrutura. Provavelmente o evento não irá ceder o auditório para 3h de palestra + discussão.

Então nesta palestra coloco como foco a performance em aplicações Java, mostrando os problemas comuns em um projeto que não consdera a performance desde a concepção, e como consequência a aplicação não se comporta bem em produção.

Como irei focar no problema e sua solução não posso deixar de mostrar as ferramentas que dão suporte a resolução desses problemas. Basicamente irei mostrar esses tópicos

  • Performance na concepção do sistema
  • Problemas e soluções comuns de memória e CPU
  • Ferramentas e Técnicas


O objetivo nesta palestra é fornecer um conjunto de técnicas, dicas e ferramentas de como abordar e resolver o problema.

Se você trabalha em alguma empresa ou projeto que está com problemas em desempenho, venha e conheça um pouco do que será mostrado.


Escrito por claudio at 2:46 PM categorizado por SouJava

Tags: soujava java palestra eventos performance

Quarta-feira, 3 Outubro 2007

JustJava 2007, nos vemos por lá

Dicas

O evento JustJava começa hoje, e pela programação de palestras, tem muita informação importante.

São 3 dias de intensa informação, com tópicos que cobrem quase todos os aspectos da tecnologia Java. E apenas uma informação, coloquei um mapa fácil para chegar ao SENAC Santo Amaro.

O Mauricio Leal, escreveu uma série de mensagens que mostram um pouco de cada palestra e seu palestrante, procurem pelas mensagens com a palavra justjava.

Também vou assistir algumas palestras, sobre tuning e garbage collector, JavaServer Faces, AOP. Como chegarei ao evento apenas na quinta-feira, não conseguirei assistir algumas palestras que gostaria.

Minha palestra "Ferramentas e Técnicas para Resolução de Problemas em Desempenho de Aplicações em Java", marcada para sexta-feira as 16h, irei mostrar por onde começar a olhar o problema, quais ferramentas usar, qual o nível de intrusão no ambiente e problemas comuns.

As muvucas irão ocorrer na quarta e quinta-feira as 19:30. Para quem ainda não conhece, as muvucas são reuniões efetuadas após o eventos, cujo objetivo é reunir experts e interessados em um tópico, com sessões de perguntas/respostas e dicas. Considero a muvuca uma das partes mais bacanas do evento, pois permite ter uma interatividade maior com palestrantes, onde podem perguntar algo sobre a palestra que não teve tempo, durante a palestra.

Escrito por claudio at 3:22 PM categorizado por SouJava

Tags: soujava java palestra eventos performance justjava

Terça-feira, 5 Junho 2007

Quantidade de threads por processo

Regularmente preciso verificar a quantidade de threads em um processo. Tanto em solaris como em linux. Coloco primeiro a versão para linux e depois a versão para Solaris.

Linux

Então coloco aqui o comando ps completo e logo abaixo um script para facilitar o monitoramento.

O comando ps

ps -p PID -o pid,user,%cpu,rss,etime,nlwp,args

Exemplo de invocação

$ ps -p 5124  -o pid,user,%cpu,rss,etime,nlwp,args
  PID USER     %CPU   RSS     ELAPSED NLWP COMMAND
 5124 claudio   8.0 122160      39:37   11 /usr/local/firefox/firefox-bin

A quantidade de threads é mostrada na coluna NLWP, que neste exemplo mostra 11 threads.

A opção -o informa quais colunas devem ser mostradas. Veja o manual do comando ps para verificar outras opções.

Note que o comando ps tem apenas uma invocação, o que torna difícil o monitoramento. Então criei um script bash, que tem as seguintes vantagens:

  • Aceita uma quantidade de repetições.
  • Repete o cabeçalho em 15 linhas
  • Aceita uma string como argumento, ao invés do nome do processo. Para não ter de ficar procurando o PID a todo momento.

threads_per_process.sh

Solaris

No solaris o comando é mais fácil: prstat

Ele aceita um parametro de repetição, que é útil para monitoramento.

Comando

prstat -c -p PID 1 3

Exemplo de invocação

$ prstat -c -p 15409 1 3
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
 15409 claudio   171M  120M sleep   59    0   4:22:25 6.6% java/29
Total: 1 processes, 29 lwps, load averages: 0.25, 0.27, 0.29
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
 15409 claudio   171M  120M sleep   59    0   4:22:25 6.3% java/29
Total: 1 processes, 29 lwps, load averages: 0.26, 0.27, 0.29

A quantidade de threads é mostrada na última coluna, chamada de NLWP, ao lado do nome do binário, que neste exemplo, mostra 29 threads.

Este monitoramento permitiu que pudesse avaliar um teste de threads que precisei realizar um tempo atrás. 

Se isto é útil para você, deixe um comentário sobre como isso lhe ajudou.

Escrito por claudio at 8:25 PM categorizado por Dicas e Scripts

Tags: java solaris dicas performance linux

Terça-feira, 15 Maio 2007

Qual é a quantidade máxima de threads suportada por um sistema ?

Tive de efetuar um teste para um cliente, onde é necessário verificar qual é a quantidade máxima de threads suportada por uma determinada máquina.

Parece simples não é ? Pois só parece, pois existem fatores que podem variar muito o resultado

  • Tamanho da pilha: -Xss
  • Tamanho máximo do heap: -Xmx
  • Capacidade computacional disponível, para funcionar o teste. Tome cuidado ao rodar isso na sua máquina de produção.
  • Em um ambiente de servidor real, o mesmo usa mecanismos de pool e prioridades, onde este teste não considera isso. Logo o sistema irá sempre suportar mais threads do que o resultado desta medição.
  • Cada thread efetua vários cálculos matemáticos, enquanto que em uma aplicação real cada thread faz operações diferentes.

Fiz um guia no ClaudiusWiki, onde as existem mais informações sobre isso e onde estão os arquivos para download, com as respectivas instruções.

Escrito por claudio at 7:49 PM categorizado por Java

Tags: java dicas performance

Quarta-feira, 21 Março 2007

Tutorial SouJava sobre Performance

Tutorial do SouJava

Desempenho é um tema que tenho forte interesse, pois lida com situações onde é necessário aproveitar os recursos computacionais existentes e tornar mais satisfatório o uso de uma aplicação.

Pois que no próximo sábado irá acontecer em São Paulo um tutorial gratuito "Envenenando Java - Dicas e Truques de Otimização", esta é a parte 1 de duas. O palestrante é Maurício "Maltron" Leal, amigo que tem presença marcante nos eventos Java nacionais.

Recomendo a todos que vão pois o Maurício tem boa didática e o tema é bastante importante para nossas profissão.

Para confirmar presença no tutorial que tem quantidade de assentos limitado, basta enviar um email para a Bianca Spazzianni, com o assunto "Confirmação tutorial SouJava - 24/03" e informe o seu nome completo no corpo do email.

Escrito por claudio at 2:00 AM categorizado por Java

Tags: java soujava tutorial performance

 
     Navegue no histórico de mensagens: « First  « Prev   1 2 3 4 5   Next »  Last »