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

Sexta-feira, 26 Março 2010

Padrão JavaDTV no Brasil

Vamos votar no padrão Java para TV Digital no Brasil !
Resumo dos passos para a votação:

1. Acesse o link http://www.abntonline.com.br/consultanacional/default.aspx
2. Será apresentada uma lista de CB . Escolha ABNT - CEE85 - Televisão  Digital
3. O projeto da Norma 06 Vol. 4 e a errata N06 Vol. 1 serão apresentados;
4. Um cadastro de email e senha será requisitado. Com o cadastro feito, você estará apto a votar.
5. Vote com a opção "Aprovado sem restrição".

=================

Se vocês ainda não sabem, o Ginga-J em sua versão definitiva, tendo como base o JavaDTV,
foi finalmente aprovado internamente no Fórum SBTVD e agora está em fase de
consulta pública aberta na ABNT.

Gostaria de pedir a vocês o grande favor de divulgar, votar e pedir votos neste período
da consulta pública.

Isso significa a aprovacão definitiva pelo público da *inclusão do Java nos
padrões do Ginga e da TV Digital Brasileira*. Isso também dará força à divulgação
do Java perante a comunidade de TV Digital dos países da América Latina que
já adotaram nosso padrão, mas estão em dúvidas sobre o Ginga (e sobre o o Ginga-J).

Por último isso significa a definitiva aceitação do JavaDTV, especificação
open source criada pela Sun e pelo Fórum SBTVD como base e núcleo do
Ginga-J (a especificação JavaDTV completa pode ser obtida aqui:
http://www.forumsbtvd.org.br/materias.asp?id=200).

Qualquer pessoa pode votar na ABNT e os passos para isso estão descritos abaixo.

É preciso se cadastrar online na ABNT (com um email válido) e depois votar.

A pessoa pode participar se colocando como filiada de uma empresa, organização
ou mesmo universidade (no caso de estudantes).

Notem que a votação termina em 05/Abril, por isso é importante rapidez na divulgação.

------------------------------

----------------------------------------------------------------------------------


O projeto da Norma 06/ Vol. 4 (Ginga-J) está sob consulta nacional até o próximo dia 5/4.

Ou  seja, estão disponíveis para a apreciação da sociedade, onde esta poderá recomendar através
do voto a aprovação do texto.

Com o Ginga -J  finalmente votado e aprovado, todas as normas do Ginga estarão oficialmente
publicadas antes da Copa do Mundo, e o Java estará finalmente dentro do padrão de TV Digital
ISDB-T Internacional, adotado hoje pelo Brasil, Peru, Argentina, Chile e Venezuela.

Vamos participar dessa votação, votando "Aprovado sem restrição".

Passos para a votação:

1. Acesse o link http://www.abntonline.com.br/consultanacional/default.aspx
2. Será apresentada uma lista de CB . Escolha ABNT - CEE85 - Televisão  Digital
3. O projeto da Norma 06 Vol. 4 e a errata N06 Vol. 1 serão apresentados;
4. Um cadastro de email e senha será requisitado. Com o cadastro feito, você estará apto a votar.
5. Vote com a opção "Aprovado sem restrição".

Escrito por claudio at 9:23 PM categorizado por Java

Tags: java noticias

Segunda-feira, 19 Outubro 2009

Geração de dumps (thread e memory) no WebSphere 6.x

Segue uma dica de como extrair um dump de threads e memória do WebSphere, funciona tanto em unix como em windows.

Acessar a interface administrativa e configurar os parametros

Navegação

Servers -> Application Servers -> Server1 -> Process Definition -> Java Virtual Machine -> Generic JVM arguments
Parâmetro:
-Xdump:system+heap+java:events=gpf+throw+user,filter=java/lang/OutOfMemoryError,request=exclusive+prepwalk
Navegação:
Servers -> Application Servers -> Server1 -> Process Definition > Environment Entries
Parâmetros:
IBM_HEAPDUMP=true
IBM_HEAPDUMP_OUTOFMEMORY=true
IBM_HEAPDUMPDIR=c:\temp

Agora criar um atalho para facilitar o acesso ao script wsadmin, no diretório WAS_HOME/bin.

Windows

* _wsadmin_comm.bat
wsadmin -conntype SOAP -user admin -password senha_do_admin %*

Unix

* _wsadmin_comm.sh
wsadmin -conntype SOAP -user admin -password senha_do_admin $*

Crie scripts JACL (script baseado em TCL) para invocação dos comandos.

Memory Dump

* heapdump.jacl
set jvm [$AdminControl queryNames type=JVM,*]
$AdminControl invoke $jvm generateHeapDump
Thread dump
* threaddump.jacl
set jvm [$AdminControl queryNames type=JVM,*]
$AdminControl invoke $jvm dumpThreads

Para gerar os dumps basta invocar os comandos

_wsadmin_comm.sh -f heapdump.jacl

Veja no diretório especificado em IBM_HEAPDUMPDIR ou no AppServer01 se os arquivos foram gerados em um deles.

Depois use ferramental adequado para analisar os dumps (Eclipse Memory Analyzer, IBM Thread Dump Analyzer).

Escrito por claudio at 4:49 PM categorizado por Java

Tags: dicas java

Palestra Java vs .Net


Irei participar do evento "Java vs .Net", que irá ocorrer em Brasília no dia 24 de outubro e 07 de novembro.

Veja o site para maiores informações.

Vou fazer uma palestra "Linguagem de programação Java e certificação" e participar de um debate com outro palestrante representante da tecnologia .Net.

Achei um momento oportuno de participar de uma discussão como esta, pois parece ainda existir dúvidas sobre a adoção da tecnologia Java ou .Net. Sem dúvida JAVA !

Não vou repetir o que já existe na internet sobre a discussão sobre Java x .Net. Pesquisem e testem por sí mesmos.

O que é importante é que a tecnologia Java é composto por um forte trio: plataforma, linguagem, bibliotecas. Que catapultaram Java para a linguagem de programação mais usada no mundo.

trabalhei com diversos clientes e sistemas de uso massivo, e todos eles usavam Java (óbvio) e Unix no servidor, pelo simples fato da plataforma windows não conseguir escalar (depoimento do próprio cliente e por experiência própria) e por consequência o .net.


Vejo algumas razões para alguém adotar .Net:

  • Não querer/poder desprender da tecnologia .Net
  • API para desktop e integração com o windows
  • Contratos de fornecimento de software combinado em larga escala

Quem tive maior curiosidade participe do evento, confira a programação de palestras.

Outros renomados palestrantes e profissionais do mundo Java irão participar do evento, assim como personalidades do mundo .net.

Conheço alguns dos palestrantes: Daniel de Oliveira (DFJUG), João Paulo Viragine (RedHat), Rafael Benevides (RedHat), Marcelo Ancelmo (Lado Servidor), Paulo Jeronimo (Lado Servidor).

Veja a chamada do evento:

O evento “Plataforma Java x Plataforma .NET - Edição DF 2009” tem como objetivo promover debates técnicos abordando diversos temas. Na edição DF 2009, o evento conta com palestrantes de alto nível técnico para representarem as plataformas Java e .NET. Diversos parceiros estão apoiando o evento, incluindo empresas, grupos de usuários, instituições de educação superior, revistas e Web Sites. O evento é beneficente e todas as inscrições representam doações para um projeto social.



Escrito por claudio at 4:25 PM categorizado por Java

Tags: java noticias palestra

Sexta-feira, 2 Outubro 2009

An internal error occurred while showing an internal error

An internal error occurred while showing an internal error.

Eclipse Internal Error

Tem coisas que só o Eclipse faz para você.

Escrito por claudio at 1:20 AM categorizado por Java

Tags: java

Terça-feira, 18 Agosto 2009

Palestra na Universidade Catolica

Dia 19 de agosto - quarta-feira - vou à Universidade Católica em Taguatinga, para participar do evento "Encontro Regional de Informática do Centro-Oeste I", fui convidado para participar com uma palestra. Irei falar sobre "Gerenciamento de Memória pela Maquina Virtual Java

Pretendo mostrar como funciona a alocação de memória e a limpeza automática (vulgo Garbage Collector), seus algoritmos e algumas boas práticas para o programador exercer um bom trabalho.

O evento será na Universidade Católica, Campus Taguatinga, Auditório Central do Prédio São João Batista de La Salle. O horário é 21h.

O evento conta com outras palestras sobre os temas: processamento de imagens, Datawarehouse e OLAP, processamento de sinais, Cloud Computing, Gestão de Segurança, Computação de Alto Desempenho, Computação Invisível.

Os minicursos também fazem parte do evento: Data Mining, PlayStation 3 em computação de alto desempenho, Ruby on Rails, Criptografia, Linux.

Update: A palestra está disponível para olhar ou copiar.

Escrito por claudio at 8:16 PM categorizado por Java

Tags: eventos java noticias palestra

Sexta-feira, 6 Março 2009

Como reduzir espaço em disco do JDK em ambiente servidor

No decorrer dos anos, as novas versões do JDK estavam acompanhadas de novas funcionalidades, bibliotecas, etc.

E sempre existiram comentários na comunidade, sobre o tamanho do JDK e o espaço ocupado pelo JDK, após a instalação.

Pois vou dar uma dica de como remover arquivos desnecessários do JDK em ambiente servidor. Na maioria das vezes, isso só será necessário se uma economia de 100MB for importante. Ou instalações em rede com imagem, para poupar tempo de download para outras estações.

A dica é baseada em um ambiente Linux 32 bits, com uma instalação padrão do JDK 6 update 12.

A instalação padrão ocupa um espaço de 239 MB. Veja a ocupação de espaço nas versões anteriores do JDK.

82M     j2sdk1.4.2_18
141M    jdk1.5.0_16
239M    jdk1.6.0_12

Uma boa evolução no espaço ocupado.

Veja os arquivos que podem ser removidos, e o tamanho que será economizado em disco.

7.9M    sample/
20M     demo/
19M     src.zip
4.3M    db/demo/
18M     db/docs/
2.1M    db/javadoc/
96K     db/lib/derbyLocale_cs.jar
100K    db/lib/derbyLocale_de_DE.jar
92K     db/lib/derbyLocale_es.jar
100K    db/lib/derbyLocale_fr.jar
96K     db/lib/derbyLocale_hu.jar
92K     db/lib/derbyLocale_it.jar
108K    db/lib/derbyLocale_ja_JP.jar
104K    db/lib/derbyLocale_ko_KR.jar
96K     db/lib/derbyLocale_pl.jar
92K     db/lib/derbyLocale_pt_BR.jar
120K    db/lib/derbyLocale_ru.jar
96K     db/lib/derbyLocale_zh_CN.jar
96K     db/lib/derbyLocale_zh_TW.jar
23M     lib/visualvm/
94M     total

Uma economia de 94 MB

Estes arquivos não são necessários em ambiente servidor. Com exceção de alguns arquivos do visualvm, que possui as bibliotecas nativas para efetuar profiling remoto, mas isso geralmente não é necessário em ambiente servidor de testes ou produção, ou alguém faz prifiling em produção ?

No caso dos arquivos de i18n do derby, prefiro usar os termos em inglês, pois acho conveniente que os termos técnicos sejam em inglês (meu ponto de vista sobre o caso).

Escrito por claudio at 1:22 AM categorizado por Java

Tags: dicas java

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