Palavras-chave: java, permgen, falta de memória, geração permanente
A máquina virtual Java tem uma área de memória limitada chamada Geração Permanente (Perm Generation), onde são armazenados objetos cuja desalocação é rara (ex.: código de classes, objetos de reflexão, pool de strings etc). Dado que esta área de memória é limitada, seu uso intenso pode gerar erros com a seguinte mensagem:
java.lang.OutOfMemoryError: PermGen space
Como a mensagem diz, isto acontece porque não há mais espaço na memória reservada para a Geração Permanente. Para que este problema não aconteça mais, use a opção -XX:MaxPermSize na inicialização da JVM. Isso aumentará o tamanho máximo da memória de Geração Permanente, como no exemplo a seguir:
java -XX:MaxPermSize=128m pacote.MinhaClasse
Neste caso, configuramos o tamanho máximo da memória de geração permanente para 128 megabytes, sendo que o tamanho padrão é 64 megabytes.
Uma demonstração pode ser feita com o código a seguir:
public class TestePerm {
public static void main(String[] args) {
int numeroDeAlocacoes = 0;
try {
System.out.println("Alocando...");
ArrayList list = new ArrayList();
String grandeString = new
BigDecimal(1000).pow(1000).toString();
for (int i = 0; i < 1000000; i++)
list.add((grandeString + numeroDeAlocacoes++).intern());
System.out.println("Fim.");
} catch (OutOfMemoryError e) {
System.out.println(e);
System.out.println("Alocacoes antes do erro: " + numeroDeAlocacoes);
}
}
}
Este programa usa o método intern() da classe String para alocar strings no pool da JVM e fazer estourar a memória de geração permanente.
A seguir, vemos dois exemplos de execuções do programa TestePerm:
$ java codare.TestePerm Alocando... java.lang.OutOfMemoryError: PermGen space Alocacoes antes do erro: 11087 $ java -XX:MaxPermSize=128m codare.TestePerm Alocando... java.lang.OutOfMemoryError: PermGen space Alocacoes antes do erro: 22183
Na primeira execução, com o MaxPermSize configurado para 64 megabytes (tamanho padrão), conseguimos colocar apenas 11087 strings no pool antes de acabar a memória permanente. No segundo caso, com 128 megabytes de MaxPermSize, conseguimos fazer 22183 alocações.
A área de geração permanente é usada intensivamente em servidores de aplicação, pois estes executam milhares de classes e ficam meses no ar. Portanto, em um ambiente de produção, nunca se esqueça de configurar um tamanho máximo adequado para a memória permanente da JVM.







8 comments
Comments feed for this article
11 Janeiro 2007 às 10:31
Eduardo Habkost
Oops. O código está pela metade por causa do “<”.
11 Janeiro 2007 às 10:42
João Del Valle
Corrigido. Valeu. ;-)
24 Janeiro 2007 às 19:28
Gilmatryx
Pô cara…
Cheguei aqui pelo google Lendo Tudo Sobre OutOfMemoryError (OOME).
Parabéns, muito abrangente e didático.
Quem sabe umas referências para o assunto :-)
Tipo:
http://www.javaspecialists.co.za/archive/Issue092.html
http://blognotfoundexception.blogspot.com/2006/10/javalangoutofmemoryerror-permgen-space.html
E valeu… Tá de parabéns!
26 Janeiro 2007 às 11:15
João Del Valle
Legal, Gilmatryx. Espero escrever mais sobre o gerencimento de memória da JVM nos próximos posts. É um assunto vasto e interessante.
23 Outubro 2007 às 9:14
Rodrigo
Cara… onde que altero esse -XX:?????
onde devo colocar esse parametro??
valeu
8 Agosto 2008 às 17:09
Leonardo Duval
Olá,
Achei bem interessante as tuas explicações sobre o erro de Perm Gen, porem ainda enfrento problemas no meu ambiente de produção que se possível gostaria da tua ajuda.
Tenho o seguinte cenário, Java 1.6, Tomcat 6.0.14 Max memory 2490Mb (por sinal, o máximo que consigo colocar no Linux, mais que isto o Java não starta, se souber como posso ampliar…). Oque ocorre é que de acordo com o uso da aplicação durante o dia ocorre o famoso “Out Of Memory Perm Gen”. Para solucionar este problema, aumentei a memoria física e o min e o max memory do java (JAVA_OPTS) porem quando as aplicações eram muito utilizadas ocorria o problema, se tiveres uma ideia de como posso fazer para solucionar serei muito grato! OBS: O servidor é reiniciado somente o Tomcat e o banco a máquina permanece sempre ligada.
Desde já obrigado.
Abraço,
Leonardo
28 Agosto 2008 às 13:24
Glaudiston
Olá Leonardo… provavelmente o parâmetro abaixo seja a solução (ou ampliá-lo)
-XX:MaxPermSize=512M
19 Setembro 2008 às 17:12
thiago
ola,
tentem isso:
http://www.jroller.com/agileanswers/entry/preventing_java_s_java_lang
tem uma explicacao interessante no primeiro posto do comentario.
“I also had these annoying Perm Gen Space OOMs when redeploying webapps. I’m using spring 1.2.8, Hibernate 3 (both with CGLIB 2.1_3), tomcat 5.5.17 and – now the problem: jdk1.5.0_06. After upgrading to jdk1.5.0_07 my Perm Gen Space gets gc’ed like it should be – no increase of Perm Gen Space, no code changes.
There were however some learnings on the way:(…) “