Вы находитесь на странице: 1из 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

Entendendo o Garbage Collector na JVM


Fique por dentro
Este artigo ir apresentar o processo de coleta de lixo na JVM, listando e explicando os vrios tipos de
coletores e orientando o leitor no processo de escolha do coletor adequado de acordo com sua aplicao.
Sero explicados tambm alguns pontos de ajuste na coleta de lixo, para obteno de melhor performance.
Ao final, falaremos sobre o G1, o novo coletor de lixo da JVM da Oracle (HotSpot).
Voc j se perguntou o que acontece quando cria um objeto usando o operador new em seu cdigo Java?
O que se passa com o pequeno espao de memria destinado ao objeto recm-criado quando o mesmo no
mais utilizado pela sua aplicao?
Quem j mais antigo em programao e j trabalhou com linguagens como C ou C++ conhece bem o
cuidado extra necessrio na alocao e liberao de memria e os problemas resultantes desta
complexidade, como o caso dos memory leaks.
O fato que em Java raramente nos preocupamos com este tipo de problema, porque a linguagem oferece
o que chamamos de coleta automtica de lixo.
Os Garbage Collectors, ou simplesmente GCs, esto presentes desde as primeiras verses do Java,
realizando seu trabalho silencioso e na grande maioria das vezes eficiente, em muitos casos at mesmo
sem serem percebidos.
Muitas vezes, principalmente quando estamos lidando com aplicaes com grande quantidade de
requisies, como uma aplicao web, para conseguir mais eficincia e performance precisamos entender
melhor o funcionamento do mecanismo de GC, suas variaes e seus ajustes.
Por ser a mquina virtual Java mais utilizada no mercado, neste artigo abordaremos as estratgias de GC
da JVM HotSpot. Existem diversas flags para parametrizar o comportamento de coleta de lixo na JVM,
mas ao invs de listarmos as flags e descrever seu uso, iremos destacar algumas delas pontualmente.
Ao final, apresentaremos o novo coletor G1, introduzido no Java 7u4. Este coletor a aposta da Oracle
para substituir os demais. Apesar de se tratar de um artigo especfico implementao da Oracle, os
conceitos vistos aqui tambm podem ser aplicados quando o leitor estiver lidando com outras
implementaes de JVM.
Coleta de lixo
Em linguagens como C,era muito comum a gesto manual de memria. Toda vez que precisvamos alocar
uma quantidade de memria dinamicamente, tnhamos que nos preocupar com a devoluo dessa
http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 1 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

memria aps o devido uso.


Listagem 1. Trecho de programa em C com alocao e liberao de memria.
int someFunction() {
int *obj = (int*) malloc(1000 * sizeof(int));
// trecho de cdigo que faz algo com o espao alocado apontado por obj
free(obj);
return 1;
}
A Listagem 1 mostra a alocao de memria suficiente para armazenar uma lista de 1.000 inteiros e
devolve a posio do primeiro espao de memria para o ponteiro de inteiros obj. Desta forma, aps o uso
da memria o programador tinha que se preocupar com a sua liberao, atravs do comando free, por
exemplo. O ponto que o desenvolvedor tinha que fazer a gesto da memria manualmente e no eram
raros os casos em que um malloc era chamado sem um free para a liberao correspondente, como
ocorre na Listagem 2.
Listagem 2. Trecho de programa em C com problema de vazamento de memria.
int someOtherFunction() {
int *obj = (int*) malloc(1000 * sizeof(int));
// trecho de cdigo que faz algo com o espao alocado apontado por obj
// onde est o free?
return 1;
}
Casoo trecho de cdigo em questo fosse executado muitas vezes, cada vez mais memria sem uso
continuaria sendo alocada. Este tipo de cenrio, conhecido como memory leak (vazamento de memria),
acabava por provocar o esgotamento de memria disponvel para a aplicao e como consequncia erros
de falta ou invaso de memria eram comuns.

http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 2 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

Observando este tipo de situao, criadores de linguagens modernas como o Java resolveram embarcar na
linguagem (no caso do Java na JVM) estratgias para coleta automtica de espaos de memria que no
so mais referenciados pela aplicao, ou simplesmente, a coleta de lixo.
Usando tcnicas avanadas a JVM consegue identificar objetos no utilizados pela aplicao e
simplesmente libera o espao de maneira automtica. O exemplo da Listagem 3 mostra um espao de
memria atribudo varivel list que coletado automaticamente depois da execuo do mtodo.
Listagem 3. Exemplo de objeto que ser coletado automaticamente pela JVM.
int someSmartFunction() {
List<Integer> list = new ArrayList<>(1000);
// Faz algo com o objeto list
return 1;
}
Repare que o cdigo em Java equivalente implementao problemtica em C, apresentada da
Listagem 2, inclusive pelo fato de no executarmos nenhum mtodo para liberao de memria. Porm,
no Java, a JVM ir liberar automaticamente o espao alocado para o objeto list algum tempo depois do
mtodo ser executado.
Este trabalho realizado pelos coletores de lixo, que nada mais so do que um cdigo embarcado na JVM
que inspeciona a memria procurando por objetos que no so mais referenciados e assim efetuar a
liberao (coleta) da memria.
Isso no significa que no podemos ter vazamentos de memria em Java, pois existem cenrios em que
objetos podem se perpetuar na memria de maneira acidental, normalmente por causa de uma falha do
programador. Veremos estes cenrios mais frente e abordaremos como evit-los.
Coletores geracionais
A coleta de lixo automtica basicamente percorre os objetos existentes na memria marcando aqueles que
de alguma maneira esto sendo utilizados ou referenciados. Os que no so marcados so
automaticamente descartados, e seu espao de memria liberado para novas alocaes.
Este processo repetido quantas vezes for necessrio durante o ciclo de vida da aplicao. A cada
execuo, ou melhor, a cada ciclo de coleta de lixo, as threads da aplicao so suspensas. Sendo assim,
quanto maior o tempo da coleta de lixo, maior o impacto na performance da aplicao.
http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 3 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

Para tentar reduzir este impacto, os desenvolvedores da JVM se apoiaram em estudos que apontam que a
grande maioria dos objetos tem um tempo de vida muito curto, ou seja, bastam poucos ciclos de coleta
de lixo para que sejam descartados.
Poucos objetos possuem uma vida mais longa. Outra constatao que existem poucos casos de objetos
velhos referenciarem objetos jovens. Tais observaes constituem a chamada hiptese geracional, e a
base para a construo dos coletores de lixos geracionais.
Com base na hiptese geracional, sabemos que boa parte da memria deve conter objetos que logo sero
descartados e uma parte menor deve conter objetos que existem hmais tempo, os objetos velhos.
Com estas informaes em mos, os engenheiros responsveis por projetar coletores de lixo perceberam
que agrupando estes dois tipos de objetos em espaos de memria separados poderiam fazer com que o
coletor visitasse menos vezes o espao dos objetos que vivem mais, reduzindo assim o tempo de coleta
de lixo e, em consequncia, diminuindo o impacto da coleta no desempenho da aplicao.
Os coletores de lixo implementados na Java Virtual Machine normalmente so chamados de coletores
geracionais, pois eles dividem a memria disponvel para a heap da JVM (limitadas pelas flags -Xmx e Xms) em blocos chamados geraes. Os blocos principais so o bloco da gerao dos objetos jovens
(young generation) e o bloco da gerao dos objetos velhos (old generation). Alm destas ainda existe a
permanent generation (ou PermGem, recentemente extinta e substituda pela MetaSpace), que
responsvel por armazenar contedo especfico como blocos de instrues dos mtodos das classes.
Quase todos os objetos alocados so inicialmente criados na young generation (existem algumas excees
que veremos adiante). Aps vrias alocaes possvel que o espao de memria destinado a esta regio
se esgote, e caso isso ocorra a coleta de lixo realizada exclusivamente nela. Objetos que j no so mais
referenciados ou, melhor, utilizados pela aplicao, so coletados nesta etapa, que frequentemente
chamada de minor collection ou coleta secundria.
Os objetos que sobrevivem um determinado nmero de coletas secundrias so copiados para a old
generation, para que a coleta secundria, que ocorre com mais frequncia, no tenha mais que se
preocupar com eles. A este processo de mover um objeto da young generation para a old generation
damos o nome de promoo. A Figura 1 mostra a diviso geracional da memria na heap da JVM e
ilustra o processo de promoo.

http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 4 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

Figura 1. Memria geracional e promoo.


Se durante a promoo a old generation tambm se esgota, ento realizada uma coleta de lixo no seu
espao, conhecida como major collection ou coleta principal. O processo de coleta de lixo nas duas
geraes conhecido por Full GC, ou coleta total. Se a sua aplicao est apresentando muitos Full GCs,
ento voc pode ter um problema srio de performance, pois este tipo de coleta um dos maiores
causadores de queda de desempenho de aplicaes Java.
As configuraes padro da JVM definem uma regio bem menor para objetos jovens do que a regio de
objetos maduros. A proporo varia de acordo com a mquina, mas podemos dizer seguramente que a old
generation por padro no mnimo duas vezes maior do que a young generation (ver BOX 1).
Se a JVM est realizando muitos Full GCs, podemos especular algumas possibilidades. Uma delas que a
young generation no est com o tamanho adequado, ento muitos objetos esto sendo promovidos para a
old generation de maneira prematura.
O padro do valor da young metade do valor da old generation. Assim, se voc definiu uma heap com
tamanho mximo de 1 Giga (-Xmx1G), por padro o tamanho mximo da young ser aproximadamente
330Mb e o da old, 670Mb.

http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 5 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

Caso a sua aplicao crie muitos objetos de vida curta, mais do que o valor padro que a young pode
suportar normalmente, estes valores podem ser ajustados atravs da flag -XX:NewRatio=<y>. Por
exemplo, o valor -XX:NewRatio=1 diz que a young deve ser do mesmo tamanho da old generation.
Alm disso, possvel ajustar o tamanho da young generation de maneira absoluta, usando a flag XX:NewSize=<y>. Por exemplo, informando XX:NewSize=800m em uma JVM com 1 Giga, voc
est reservando 800 Mb para a Young e apenas 200 Mb para a Old Generation.
O ajuste de tamanho entre a Young e a Old generation so fundamentais para um desempenho melhor do
coletor de lixo. Uma das sugestes da Oracle deixar a JVM ajustar sozinha esta proporo, mas para isso
voc no pode definir a heap inicial (-Xms) igual heap mxima (-Xmx).
Desta forma, a JVM aprende a melhorar o valor da proporo cada vez que solicita mais memria ao
sistema operacional, at atingir o mximo (-Xmx). Esta abordagem, no entanto, possui um problema, pois
em aplicaes que rodam em containers mais pesados, como os servidores de aplicao, durante o boot do
container a JVM pode atingir seu mximo de heap, e com isso o tuning que a JVM fez pode ser especfico
para situaes de boot, no considerando o uso normal da aplicao, exigindo assim alguns ciclos de Full
GC para se reajustar.
Ajustes na promoo
Outro fator que pode ser ajustado o momento da promoo do objeto da young para a old generation.
Por padro, um objeto promovido apenas se sobreviver a 15 ciclos de coletas secundrias. Na prxima
coleta, se o objeto ainda estiver vivo, ele ser promovido para a Old generation.
Este nmero, contudo, pode ser ajustado dependendo da aplicao. Voc pode obter resultados melhores
ajustando tanto para cima como para baixo. Para isto, usamos a flag -XX:MaxTenuringThreshold=
<n>.
Conforme informado anteriormente, a maioria dos objetos alocada na Young Generation, porm existem
excees. Isso ocorre porque alguns objetos so alocados diretamente na Old Generation por consumir
muita memria (objetos grandes).
A JVM preventivamente aloca este tipo de objeto diretamente na Old Generation para evitar o
esgotamento precoce da Young Generation. Este evento chamado de promoo prematura e se ocorrer
em grande quantidade pode comprometer o bom funcionamento do GC, ocasionando grandes ciclos de
Full GC.
Para configurar o tamanho de objetos que devem ser alocados diretamente na Old Generation podemos
usar a flag -XX:PretenureSizeThreshold=<n>, onde n o tamanho em bytes.

http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 6 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

BOX 1. Young Generation


Neste artigo, estamos explicando de maneira simples a promoo de objetos de uma gerao para outra. O
fato que a JVM ainda divide a Young generation em trs sub-regies: uma regio chamada eden, onde
todos os objetos so inicialmente alocados, e outras duas regies, chamadas survivor from e survivor to
(sobreviventes).
Inicialmente os objetos so alocados no eden. Caso sobrevivam coleta secundria, so copiados para um
dos survivors, juntamente com todos os sobreviventes do outro survivor. A ideia manter sempre o eden e
uma regio survivor limpos, para facilitar a alocao de objetos e evitar problemas de fragmentao na
Young Generation. Aps vrias idas e vindas entre um survivor e outro (MaxTenuringThreshold), o objeto
pode ento ser promovido para a Old generation. A Figura 2 ilustra o funcionamento do eden e dos
survivors.

http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 7 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

Figura 2. Eden e survivor spaces.


Monitorando a coleta de lixo
Antes de nos aprofundarmos nos tipos de coletores disponveis na JVM, faamos uma pausa para explicar
algumas formas de observarmos a ocupao da memria e a coleta de lixo na JVM. O intuito
instrumentar o leitor com ferramentas que viabilizem a anlise do comportamento da sua aplicao e
assim auxiliem na deciso sobre uma eventual troca do tipo de coletor, os quais sero detalhados logo
mais neste artigo.

http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 8 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

Para monitorar a coleta de lixo na JVM temos disponveis diversas ferramentas no mercado. Algumas
delas so distribudas juntamente com o JDK, como o caso do JConsole, JVisualVM e mais
recentemente o JMC (Java Mission Control), localizados na pasta bin do JDK. Estas ferramentas
possuem interface grfica e so razoavelmente simples de operar. Alm destas, h outra alternativa,
denominada jStat, tambm distribuda no JDK. O jStat uma ferramenta de console e por isso
extremamente fcil de utilizar.
O jStat se conecta a uma JVM em execuo e captura diversas informaes relativas memria, exibindo
o resultado no console. Ele possui diversas opes de execuo, dentre elas a gcutil. Para completar a
execuo desse comando, devemos informar o nmero do processo (PID) que queremos monitorar, de
quanto em quanto tempo queremos capturar os dados (em milissegundos) e por quantas vezes. Sendo
assim, o comando:
$ jstat gcutil 4433 1000 5
Ir instrumentar o processo 4433 por cinco vezes com um intervalo de um segundo entre elas. O resultado
semelhante ao contedo exposto na Listagem 4.
Listagem 4. Resultado da execuo do comando jstat gcutil 4433 1000 5.
S0

S1

YGC

YGCT

FGC

FGCT

GCT

0.00

99.96

33.32

17.24

99.16

15

0.087

0.240

0.327

0.00

99.96

33.32

17.24

99.16

15

0.087

0.240

0.327

0.00

99.96

33.32

17.24

99.16

15

0.087

0.240

0.327

0.00

99.96

33.32

17.24

99.16

15

0.087

0.240

0.327

0.00

99.96

33.32

17.24

99.16

15

0.087

0.240

0.327

O resultado uma tabela com as seguintes colunas:


S0, S1 e E: Survivor 0, Survivor 1 e Eden, respectivamente. Compem a Young Generation;
O: representa a Old Generation, que est com 17,24% de seu espao ocupado por objetos;
P: representa a PermGem, local onde a JVM aloca objetos especiais como contedo de classes.
YGC: informa a quantidade de vezes que a JVM executou uma coleta de lixo na Young Generation;
YGCT: indica o tempo em segundos que a coleta demorou na ltima vez;
FCG: informa quantos Full GCs foram executados;
FGCT: exibe o tempo de coleta em segundos da Old Generation;

http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 9 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

GCT: mostra o tempo somado da coleta na Young e Old generations.


O resultado dessa execuo nos indica a ocupao de cada rea de memria da JVM. Logo, podemos
concluir os momentos em que a coleta realizada, pois estas reas ficam vazias e os contadores de coleta
so incrementados.
Outra forma de monitorar as coletas de lixo na JVM ativando o log do coletor de lixo, atravs das flags XX:+PrintGC -XX:+PrintGCDetails -Xloggc:<file>. Deste modo, para cada coleta gerado um
registro no arquivo de log indicado.
Usando este tipo de ferramenta em uma aplicao em execuo possvel detectar se a aplicao est
realizando muitas coletas na Young Generation ou pior, Full GCs, que podem causar queda significativa
na performance. Alm disso, consegue-se dimensionar os tamanhos destas reas ou trocar o tipo de
coletor para obter melhor performance. Ainda neste artigo iremos nos aprofundar nos tipos de coletores e
seus pontos e fortes fracos.
Pare o mundo, o coletor de lixo chegou
Independentemente do tipo de coletor utilizado, o processo de coleta de lixo na JVM do tipo stop the
world (pare o mundo). Este apelido se d devido ao fato que durante a coleta de lixo as threads da
aplicao so completamente interrompidas para que as threads dos coletores possam realizar o seu
trabalho.
Existem alguns coletores que tentam diminuir o tempo de parada das threads da aplicao utilizando
concorrncia em algumas fases da coleta (o que ser visto em detalhes adiante), porm at mesmo eles
possuem algumas fases de interrupo.
Tipos de Coletores
Para compreender os tipos de coletores de lixo oferecidos na JVM HotSpot, convidamos o leitor para uma
pequena abstrao. Imagine que voc est em um trem em alta velocidade e que dentro do seu vago
existem vrias pessoas. No nosso exerccio, essas pessoas no tm muita educao e ficam constantemente
jogando lixo no cho. Tenso, voc observa que o cho comea a ficar tomado pela sujeira.
O trem desacelera at parar completamente em uma plataforma. Depois de parado, as portas se abrem e
apenas um faxineiro entra. Devidamente uniformizado ele comea a recolher todo o lixo no cho. Aps a
concluso do trabalho o faxineiro sai, as portas se fecham e o trem retorna a sua jornada, agora com o
vago limpo. Algum tempo depois o cho j est tomado de lixo novamente.
O trem desacelera mais uma vez e para na estao. As portas se abrem, mas desta vez quatro faxineiros
entram e rapidamente limpam o vago, pois agora esto em maior nmero, saem e as portas se fecham. O

http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 10 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

trem parte novamente e no tarda muito para o cho ficar sujo mais uma vez. Desta vez o trem para em
uma plataforma, as portas se abrem e uma nova equipe de quatro coletores entram, porm desta vez as
portas se fecham e o trem parte.
Enquanto o trem est em movimento os faxineiros realizam os seus trabalhos. Quando eles concluem a
limpeza, o trem para novamente em outra plataforma, as portas se abrem, os faxineiros saem e o trem
retoma a viagem.
Voltando ao mundo virtual, se considerarmos que o trem representa as threads da nossa aplicao, o lixo
jogado no cho representa os objetos alocados e no mais utilizados e os faxineiros como as threads do
coletor de lixo, os trs cenrios descrevem, de maneira simplista, os trs principais tipos de coletores de
lixo da JVM:
1. SerialGC: onde apenas um faxineiro ou apenas uma thread coleta o lixo;
2. ParallelGC: onde vrios faxineiros ou vrias threads coletam o lixo;
3. Concurrent Mark Sweep: onde vrios faxineiros ou vrias threads coletam o lixo enquanto a thread
da aplicao segue em execuo.
Deixando este cenrio abstrato de lado, a seguir veremos uma explicao um pouco mais detalhada de
cada tipo de coletor de lixo aqui exposto.
O coletor serial
Como o prprio nome indica, o Serial GC, ou coletor em srie (ativado pela flag XX+UseSerialGC) tem
esse nome porque utiliza apenas uma thread para coleta de lixo. Quando este coletor acionado todas as
threads da aplicao so suspensas. importante ressaltar que quando executado na old generation (em
um Full GC), este coletor realiza uma fase adicional de compactao dos objetos sobreviventes, para evitar
a fragmentao do espao e otimizar as alocaes (ver BOX 2).
um dos coletores mais antigos na JVM e foi desenvolvido em um momento em que mquinas multicore
ainda no eram to comuns. Por usar apenas uma thread, o coletor mais simples e ainda recomendvel
para aplicaes com pouca memria ou que rodem em mquinas com um ou dois processadores.
Com o crescimento das plataformas como servio (PaaS), que normalmente disponibilizam containers
com recursos limitados, este coletor voltou a ser utilizado com frequncia pois se adequa bem a este tipo
de ambiente.
BOX 2. Fragmentao e Compactao
Normalmente a alocao de objetos na memria da JVM acontece de maneira sequencial, ou seja, um
http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 11 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

objeto alocado ao lado do outro, sem espaos entre eles. Porm, com o passar do tempo alguns objetos
so coletados e outros no, gerando assim espaos vazios entre objetos sobreviventes.
Com a memria fragmentada, as novas alocaes se tornam mais lentas, pois a JVM tem que percorrer os
espaos livres em busca de uma lacuna com o tamanho suficiente para o novo objeto. Por isso,
ocasionalmente a JVM realiza um processo de compactao da memria, no qual todos os objetos so
compactados e o espao livre novamente se torna contguo. A Figura 3 demostra esse processo.

Figura 3. Fragmentao e compactao.


O coletor paralelo
o coletor default da maioria das JVMs (ativado pela flag -XX:+UseParallelGC e XX:+UseParallelOldGC). Assim como o Serial GC, durante a execuo do Parallel GC, ou coletor
paralelo, todas as threads da aplicao so suspensas.
Porm, esse coletor utiliza diversas threads para realizar o trabalho, reduzindo assim o tempo de
suspenso da aplicao. Tambm como o Serial GC, este coletor faz uma compactao da old generation
aps a Full GC. Devido a sua caracterstica multithread, as pausas de GC tendem a diminuir
consideravelmente, e sendo assim, este tipo de coletor recomendvel para aplicaes que rodem em
ambiente um pouco mais robustos, com vrios processadores disponveis e com uma quantidade de
memria acima de 512Mb.
O coletor concorrente
O Concurrent Mark Sweep GC o coletor mais complexo da JVM (ativado pela flag XX:+UseConcMarkSweepGC), sendo realizado em trs etapas. Na primeira e na terceira etapas as
threads da aplicao so suspensas completamente. J na segunda fase do processo a coleta realizada
concorrentemente com as threads da aplicao.
Por consequncia, as pausas da coleta so menores e mais distribudas durante o ciclo de vida da
aplicao, o que resulta em pausas menores e mais frequentes. Aplicaes que no podem abrir mo de
http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 12 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

pausas menores, como aplicaes real-time, devem optar por este coletor.
Em contrapartida, este coletor, por ser mais complexo, utiliza mais ciclos de CPU e consequentemente
reduz o desempenho geral da aplicao. Outro problema dessa coleta que fica impossvel realizar a
compactao dos objetos sobreviventes, pois novos objetos podem ser criados durante sua execuo.
Para resolver isso, este coletor realiza um Full GC Serial quando a memria atinge um certo nvel de
fragmentao. Contudo, se este tipo de situao ocorrer com frequncia, deve-se optar por outro coletor
ou realizar algum ajuste de tamanho entre a young e a old generation.
A Figura 4 apresenta graficamente a situao das threads da aplicao e do coletor de lixo nos trs tipos
de coletores que acabamos de explicar.

Figura 4. Situao das threads durante a coleta de lixo.


A escolha do coletor adequado
A escolha do coletor vai depender muito da sua aplicao e do ambiente em que ela ser executada. Agora
que entendemos a diferena entre os trs principais coletores da JVM, podemos adotar a seguinte regra
para este momento:
Se voc tem recursos limitados de memria ou processador (mquinas com um processador), escolha o
Serial GC. Qualquer outro coletor paralelo no ter efeito positivo, pois voc ter vrias threads de coleta
de lixo competindo para usar um nico ncleo;
Se voc tem mquinas com vrios ncleos e uma boa memria, pode considerar utilizar o ParallelGC ou o
CMS. O que difere entre os dois, basicamente, que no Parallel as pausas sero maiores, porm menos
frequentes, e no CMS ocorrer o inverso, menos pausas, porm mais frequentes. Depende muito do tipo

http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 13 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

da sua aplicao a escolha entre um ou outro.


G1, o coletor definitivo?
Um dos problemas dos coletores citados anteriormente a pouca flexibilidade da diviso da heap entre
young e old generation. Tanto da maneira configurvel atravs da flag -XX:NewRatio=<y>, como no
ajuste automtico feito pela JVM, no existe muita margem para mudana deste valor quando a alocao
atinge o total da memria definida para a JVM (definido pela flag -Xmx).
Pensando em JVMs rodando em ambientes com uma boa quantidade de memria (acima de 4GB
disponvel para a JVM o recomendado), a Oracle desenvolveu o coletor chamado G1 (ativado pela flag XX:+UseG1GC). Este coletor a aposta da Oracle para substituir e simplificar a configurao da coleta
de lixo na HotSpot.
Apesar de ainda ser um coletor geracional, no G1 as regies no so blocos contguos de memria, mas
sim blocos virtuais.
Na prtica, a heap dividida em diversas regies menores de igual tamanho que podem variar de 1 a 32
Mb, dependendo do tamanho total da heap. A Figura 5 mostra a diviso da memria da JVM quando
usamos o G1.

Figura 5. Representao grfica da memria quando o coletor G1 usado.


Como podemos observar, os espaos no so mais blocos contguos. neste pequeno detalhe que reside o
grande diferencial deste coletor. Com esta abordagem, o espao destinado Young e Old generation
podem ser ajustados dinamicamente durante todo o ciclo de vida da aplicao. Alm disso, o G1 consegue
http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 14 of 15

Entendendo o Garbage Collector na JVM

11/01/15 10:47 AM

identificar as regies mais sujas (com mais lixo do que objetos vivos) e prioriza a coleta nestas regies,
movendo os objetos sobreviventes para outras regies, fazendo com que elas fiquem limpas, otimizando
assim as alocaes.
O nome G1 uma sigla para Garbage First (primeiro o lixo), pelo fato deste coletor privilegiar a
execuo da coleta nas regies com maior quantidade de lixo.
Tunando o G1
Para usar o G1, devemos informar a flag -XX:+UseG1GC para a JVM. As flags citadas anteriormente,
como -Xms, -Xmx, -XX:NewRatio=<n> e -XX:MaxTenuringThreshold=<n>, tambm so
vlidas para este coletor. Outras flags que podem ser utilizadas para ajustar o G1 so:
-XX:MaxGCPauseMillis=n: Permite configurar o valor mximo aceitvel, em milissegundos, para
uma pausa de GC. Outros coletores tambm possuem esta flag. A JVM vai se esforar para respeitar este
valor, se for necessrio realizando mais coletas para manter o tempo dentro do especificado, mas pode
falhar (silenciosamente) nesta tentativa;
-XX:InitiatingHeapOccupancyPercent=n: Esta flag configura o percentual de ocupao necessria
para iniciar um ciclo de coleta de lixo. Se for informado o valor 0, a JVM ir realizar ciclos de coleta em
intervalos de tempo constantes. O valor padro 45, que informa que o ciclo de coleta deve ser disparado
quando a ocupao da heap for de 45%;
-XX:G1HeapRegionSize=n: Conforme explicado anteriormente, o G1 divide a heap em regies. Esta
flag permite configurar exatamente o tamanho destas regies. Caso ela no seja configurada, a JVM ir
deduzir um valor entre 1 e 32Mb, baseado no tamanho total da heap.
Nota: O mercado ainda olha para o G1 como uma aposta para o futuro, pois a prpria Oracle j anunciou
que este coletor ainda est em fase de aprimoramento.
Cedo ou tarde nos depararemos com a necessidade de realizar algum ajuste no coletor de lixo da JVM,
principalmente quando lidarmos com problemas de performance em aplicaes Java. Felizmente com as
ferramentas de instrumentao disponveis no JDK possvel identificar que estes problemas podem ser
oriundos de uma estratgia de coleta de lixo inadequada para o conjunto aplicao-ambiente.
Neste contexto, compreendendo melhor o funcionamento dos coletores disponveis na JVM, torna-se
vivel realizar uma escolha mais assertiva do tipo de coletor a ser empregado e tambm efetuar ajustes
finos no processo de coleta para obter o mximo desempenho.

http://www.devmedia.com.br/entendendo-o-garbage-collector-na-jvm/31539

Page 15 of 15

Вам также может понравиться