Pergunta

Estou correndo Tomcat6 em jre6 da Sun e cada par implanta recebo OutOfMemoryException: PermGen. Eu fiz o Googling de soluções PermGen e tentei muitas correções. Nenhum trabalho. Eu li um monte de coisas boas sobre JRockit da Oracle e como a sua atribuição PermGen pode ser shows em tamanho (comparar com 128M de Sun) e enquanto ele não resolver o problema, ele me permitiria redistribuir 100 vezes entre as excepções PermGen em comparação com 2 vezes agora.

O problema com JRockit é usá-lo em produção você precisa comprar WebLogic que custa milhares de dólares. Que outras opções (gratuito) existem que são mais tolerantes de expansão PermGen? Como o abaixo JVMs fazer nesta área?

  • IBM JVM
  • Open JDK
  • Blackdown
  • Kaffe

... outros?

Update: Algumas pessoas têm perguntado por que eu pensei PermGen max foi 128M. A razão é porque a qualquer momento eu tentar elevá-la acima de 128M minha JVM falha a inicialização:

[2009-06-18 01:39:44] [info] Error occurred during initialization of VM [2009-06-18 01:39:44] [info] Could not reserve enough space for object heap [2009-06-18 01:39:44] [395 javajni.c] [error] CreateJavaVM Failed

É estranho que ele falhar tentando reservar espaço para o objeto pilha , embora eu não tenho certeza "a" pilha em vez dela de "a" pilha.

Eu inicializar o JVM com 1024MB inicial e 1536MB heap max.

Vou fechar esta questão, uma vez que foi respondida, ie. "Comutação é inútil" e pedir ao invés por que meu Sun JVM falhar com maior PermGen configurações?

Foi útil?

Solução

Concordo com Michael Borgwardt em que você pode aumentar o tamanho PermGen, eu discordo que é principalmente devido a vazamentos de memória. espaço PermGen é comido-se de forma agressiva por aplicações que implementam o uso pesado de Reflexão. Então, basicamente, se você tiver um aplicativo de Primavera / Hibernate executado em Tomcat, estar preparado para bater naquele espaço PermGen-se muito.

Outras dicas

O que lhe deu a ideia de que JVM da Sun é restrito a 128M PermGen? Você pode configurá-lo livremente com o XX: opção de linha de comando MaxPermSize; o padrão é 64M.

No entanto, a verdadeira causa do seu problema é provavelmente um vazamento de memória no seu aplicativo que impede as classes de ficar lixo coletado; estes podem ser muito sutil, especialmente quando ClassLoaders estão envolvidos, uma vez que tudo o que precisamos é uma única referência a qualquer uma das classes, em qualquer lugar. Este artigo descreve o problema em detalhe, e esta sugere maneiras de corrigi-lo.

Tecnicamente, o "PermGen" pool de memória é uma coisa Sun JVM. Outros JVMs não chamá-lo assim, mas todos eles têm a idéia de um ou mais não-heap pools de memória.

Mas se você tem um problema com permgen em sua Sun JVM, movendo-se para outro JVM é muito improvável resolver nada, ele só vai manifestar-se sob um nome diferente.

Se vários reafectações estão causando os seus problemas, apenas aumentar PermGen da VM até grandes valores. Nós tentamos JRockit uma volta, enquanto por causa deste mesmo problema, e ele sofre do mesmo exaustão reafectação. Voltamos a Sun JVM.

Alterar JVM não é uma panacéia. Você pode obter novos problemas inesperados (por exemplo, consulte um artigo sobre o lançamento de um aplicativo em 4 JVM diferente).

  • Você pode ter um vazamento de classe (por exemplo, através de carregadores de classe) que na maioria das vezes acontece em redeploy. Francamente, eu nunca vi trabalhando redeploy quente em Tomcat (esperança de ver um dia).
  • Você pode ter paramaters JVM incorretas (por exemplo, para Sun JDK 6 64 bits -XX: + UseParNewGC interruptor leva a vazar segmento PermGen de memória Se você adicionar opções adicionais:. -XX: + UseConcMarkSweepGC -XX: + CMSClassUnloadingEnabled-XX: + CMSPermGenSweepingEnabled a situação será resolvida. engraçado, mas eu nunca conheci acima vazamento mencionado com Sun JDK 6 32 bits). Fazer a ligação para um artigo "Sintonia JVM Garbage Collection for Production Deployments".
  • O seu pedaço PermGen pode não ser suficiente para classes de carga e informações relacionadas (na verdade que na maioria das vezes acontece depois redeploy sob Tomcat, as classes de idade ficar na memória e novos são carregamento)

Da minha experiência passada, a depuração esse tipo de vazamento é um do tipo mais complicado de depuração que eu já tive.

[ATUALIZADO]

artigo Útil como eliminar ligação carregador de classe em um redeploy aplicação.

Eu uso JRockit e eu ainda obter erros PermGen se eu não colidir acima (via XX: MaxPermSize) a memória. Eu também não pode obter qualquer coisa para trabalhar para evitar isso (que não aumentá-la).

Perm gen é provavelmente a memória mais simples de manusear, duvido que haveria muita diferença entre as várias implementações vm.

Certifique-se de todas essas configurações do Tomcat que estão marcados desligar na produção estão desligados na produção.

Sim, algumas estruturas que geram um monte de aulas de uma mosca, mas eles devem ser limpeza após si, e, em qualquer caso, você pode caber mais do que algumas aulas de 128Mb.

A sério, se perm gen continua a subir, então isso é um vazamento de um devem ser fixados, embora possa não ser o seu problema para correção.

O IBM JVM não (e não em 2009) têm uma permgen. Você pode ler mais sobre a sua Generational Concurrent Garbage Collector que é a sua GC padrão para Java 7.

Eu às vezes executar o IDE Eclipse na IBM JVM especificamente porque com meus plugins favoritos seria frequentemente encher permgen do HotSpot JVM. Claro, houve provavelmente um vazamento de memória que alguém deveria ter fixado, mas enquanto isso o meu IDE não estava falhando e eu não estava ocupado fazendo experiências com diferentes configurações.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top