O que causa o PerOGen OutOfMemoryError no JBoss?

8

Qual é a causa subjacente de um PerOGen OutOfMemoryError no JBoss?

Estou executando o JBoss AS 4.2.2 no meu ambiente de desenvolvimento, e isso ocorre após a reimplantação do meu aplicativo da Web um grande número de vezes.

O blog de Christian Vest Hansen oferece opções da JVM que ajudam muito , mas não resolve o problema completamente:

-XX:+UseConcMarkSweepGC
-XX:+CMSPermGenSweepingEnabled
-XX:+CMSClassUnloadingEnabled
-XX:MaxPermSize=128m
    
por Peter Hilton 05.05.2009 / 10:27

3 respostas

5

Como já foi mencionado, provavelmente você está tendo vazamentos de carregadores de classes. Por alguma razão, suas aulas não estão sendo descarregadas. Isso pode acontecer por dois motivos

  • Objetos dessas classes ainda existem no heap, os objetos sempre fazem referência a sua classe ou
  • O carregador de classes é referenciado em algum lugar, por qualquer motivo, os carregadores de classes fazem referência a suas classes para não carregá-las duas vezes

Não há solução completa para esse problema. Uma ferramenta útil para ajudá-lo a encontrar a causa raiz é a Ferramenta Analisador de Memória do Eclipse , que você pode aplicar para um dump de heap de sua JVM (é possível ativar dumps de heap nos OOMs com a opção -XX: + HeapDumpOnOutOfMemoryError). Talvez comece a procurar objetos java.lang.Class no seu aplicativo da web para ver por que eles estão sendo mantidos vivos. Infelizmente, o PermGen normalmente não faz parte de um dump de heap da JVM, portanto, você só pode tentar localizar artefatos correlatos no restante do heap (Objetos de classe não são armazenados no PermGen se não me engano, apenas o código de byte real é, por favor me corrija se eu estiver errado).

HTH.

Editar:
Dave Cheney sugere em um comentário que java.lang.Class-objects são de fato parte do PermGen, e não estão incluídos em um dump de heap hotspot normal. A menos que você tenha uma JVM que grava essas informações no despejo de heap, precisará de uma abordagem diferente. Você ainda pode procurar instâncias de seus objetos, mas se você estiver vazando classes / carregadores de classes (ambos infelizmente implicam um ao outro), parece que você precisa procurar por outros sinais (objetos de metadados do JBoss, etc).

    
por 05.05.2009 / 11:46
2

A causa subjacente é referências a classes que foram descartadas com vazamento fora de seu classloader, impedindo que a JVM descarregue essas classes da geração permanente. Esses sinalizadores que você usa podem fazer com que a JVM elimine agressivamente as classes que são descarregáveis, mas não resolverá o problema subjacente.

Há uma boa e completa explicação complexa aqui

    
por 05.05.2009 / 10:35
1

A causa do erro de perda de memória PermGen é o aplicativo reimplementado. A causa subjacente é vazada Objetos de classe no PermGen das reimplementações.

Naturalmente, a solução alternativa é reiniciar a JVM após um determinado número de reimplementações.

Este é um problema muito difícil de resolver totalmente, embora com algumas investigações você possa fazer grandes melhorias. É aqui que você começa: quando seu aplicativo da Web for interrompido, certifique-se de que:

  • all Os tópicos que você iniciou estão parados
  • all ThreadPools que você iniciou estão desativados
  • todas referências estáticas que você pode liberar são liberadas

Estas são algumas das coisas que podem fazer com que um objeto de classe fique preso no PermGen.

Além disso, observe que nem todas as JVMs (ou todas as versões de JVMs) terão objetos de Classe GC no PermGen. Se você estiver executando uma JVM ou uma versão de uma JVM que não contenha objetos GC Class no PermGen, sua única opção será reiniciar a JVM após um determinado número de reimplementações. Isso provavelmente não se aplica a você, dadas as opções da JVM que você mencionou.

    
por 05.05.2009 / 17:05