Recentemente, encontrei este erro no meu aplicativo da web:
java.lang.OutOfMemoryError: espaço PermGen
É um aplicativo típico Hibernate / JPA + IceFaces / JSF em execução no Tomcat 6 e JDK 1.6. Aparentemente, isso pode ocorrer após a reimplantação de um aplicativo algumas vezes.
O que causa e o que pode ser feito para evitá-lo? Como soluciono o problema?
Respostas:
A solução foi incluir esses sinalizadores na linha de comando da JVM quando o Tomcat for iniciado:
Você pode fazer isso desligando o serviço tomcat, entrando no diretório Tomcat / bin e executando tomcat6w.exe. Na guia "Java", adicione os argumentos à caixa "Opções de Java". Clique em "OK" e reinicie o serviço.
Se você receber um erro, o serviço especificado não existe como serviço instalado, execute:
onde servicename é o nome do servidor conforme exibido em services.msc
Fonte: comentário do orx no Eric's Agile Answers .
fonte
É melhor você tentar
-XX:MaxPermSize=128M
do que-XX:MaxPermGen=128M
.Não sei dizer o uso preciso desse conjunto de memórias, mas isso tem a ver com o número de classes carregadas na JVM. (Assim, ativar o descarregamento de classe para o tomcat pode resolver o problema.) Se seus aplicativos gerarem e compilarem classes durante a execução, é mais provável que você precise de um pool de memória maior que o padrão.
fonte
Os erros de PermGen do servidor de aplicativos que ocorrem após várias implantações provavelmente são causados por referências mantidas pelo contêiner nos carregadores de classe dos aplicativos antigos. Por exemplo, o uso de uma classe personalizada no nível do log fará com que as referências sejam mantidas pelo carregador de classes do servidor de aplicativos. Você pode detectar esses vazamentos entre carregadores de classes usando ferramentas modernas de análise JVM (JDK6 +), como jmap e jhat, para verificar quais classes continuam sendo mantidas em seu aplicativo e redesenhar ou eliminar seu uso. Os suspeitos comuns são bancos de dados, registradores e outras bibliotecas no nível da estrutura base.
Consulte Vazamentos no Classloader: a temida exceção "java.lang.OutOfMemoryError: PermGen space" e, especialmente, sua postagem de acompanhamento .
fonte
Os erros comuns que as pessoas cometem é pensar que o espaço de pilha e o espaço permanente são iguais, o que não é de todo verdade. Você pode ter muito espaço restante na pilha, mas ainda pode ficar sem memória em permgen.
As causas comuns de OutofMemory no PermGen são ClassLoader. Sempre que uma classe é carregada na JVM, todos os seus metadados, juntamente com o Classloader, são mantidos na área PermGen e serão coletados como lixo quando o Classloader que os carregou estiver pronto para a coleta de lixo. No Case Classloader, há um vazamento de memória, pois todas as classes carregadas por ele permanecerão na memória e causarão permGen fora da memória, uma vez que você o repita algumas vezes. O exemplo clássico é Java.lang.OutOfMemoryError: PermGen Space no Tomcat .
Agora, existem duas maneiras de resolver isso:
1. Encontre a causa do vazamento de memória ou se houver algum vazamento de memória.
2. Aumente o tamanho do PermGen Space usando os parâmetros
-XX:MaxPermSize
e da JVM-XX:PermSize
.Você também pode verificar 2 Solution of Java.lang.OutOfMemoryError em Java para obter mais detalhes.
fonte
-XX:MaxPermSize and -XX:PermSize
?? Não consigo encontrarcatalina.bat
. Minha versão do tomcat é5.5.26
.Use o parâmetro de linha de comando
-XX:MaxPermSize=128m
para uma Sun JVM (obviamente substituindo 128 pelo tamanho que você precisar).fonte
Tente
-XX:MaxPermSize=256m
e se persistir, tente-XX:MaxPermSize=512m
fonte
XX:MaxPermSize=1024m
:)Eu adicionei
-XX: MaxPermSize = 128m
(você pode experimentar o que funciona melhor) ao VM Arguments enquanto estou usando o eclipse ide. Na maior parte da JVM, o PermSize padrão é de cerca de 64 MB, que fica sem memória se houver muitas classes ou um grande número de Strings no projeto.Para eclipse, também é descrito na resposta .
PASSO 1 : Clique duas vezes no servidor tomcat na guia Servidores
ETAPA 2 : Abra o Conf de inicialização e adicione
-XX: MaxPermSize = 128m
ao final dos argumentos de VM existentes .fonte
Também tenho enfrentado esse problema ao implantar e desimplementar um aplicativo Web complexo, e pensei em adicionar uma explicação e minha solução.
Quando implanto um aplicativo no Apache Tomcat, um novo ClassLoader é criado para esse aplicativo. O ClassLoader é usado para carregar todas as classes do aplicativo e, na desimplantação, tudo deve desaparecer bem. No entanto, na realidade, não é tão simples.
Uma ou mais das classes criadas durante a vida útil do aplicativo Web mantém uma referência estática que, em algum ponto da linha, faz referência ao ClassLoader. Como a referência é originalmente estática, nenhuma quantidade de coleta de lixo limpará essa referência - o ClassLoader e todas as classes carregadas vieram para ficar.
Depois de algumas reimplantações, encontramos o OutOfMemoryError.
Agora isso se tornou um problema bastante sério. Eu poderia garantir que o Tomcat fosse reiniciado após cada reimplantação, mas isso derrubaria todo o servidor, em vez de apenas o aplicativo que está sendo reimplantado, o que geralmente não é possível.
Então, em vez disso, montei uma solução em código, que funciona no Apache Tomcat 6.0. Não testei em nenhum outro servidor de aplicativos e devo enfatizar que é muito provável que isso não funcione sem modificação em nenhum outro servidor de aplicativos .
Eu também gostaria de dizer que pessoalmente odeio esse código e que ninguém deve usá-lo como uma "solução rápida" se o código existente puder ser alterado para usar métodos adequados de desligamento e limpeza . A única vez que isso deve ser usado é se houver uma biblioteca externa da qual seu código dependa (no meu caso, era um cliente RADIUS) que não fornece um meio de limpar suas próprias referências estáticas.
Enfim, continue com o código. Isso deve ser chamado no ponto em que o aplicativo não está sendo implementado - como o método de destruição de um servlet ou (a melhor abordagem) o método contextDestroyed de um ServletContextListener.
fonte
A
java.lang.OutOfMemoryError: PermGen
mensagem de espaço indica que a área da geração permanente na memória está esgotada.Qualquer aplicativo Java pode usar uma quantidade limitada de memória. A quantidade exata de memória que seu aplicativo específico pode usar é especificada durante a inicialização do aplicativo.
A memória Java é separada em diferentes regiões, que podem ser vistas na imagem a seguir:
Metaspace: nasce um novo espaço de memória
O JDK 8 HotSpot JVM agora está usando memória nativa para a representação dos metadados da classe e é chamado Metaspace; semelhante ao Oracle JRockit e IBM JVM.
A boa notícia é que isso significa que não há mais
java.lang.OutOfMemoryError: PermGen
problemas de espaço e que você não precisa mais ajustar e monitorar esse espaço de memória usando o Java_8_Download ou superior.fonte
1) Aumentando o tamanho da memória PermGen
A primeira coisa que se pode fazer é aumentar o tamanho do espaço de pilha de geração permanente. Isso não pode ser feito com os argumentos comuns da JVM –Xms (definir tamanho de heap inicial) e –Xmx (definir tamanho máximo de heap), pois, como mencionado, o espaço de heap de geração permanente é totalmente separado do espaço de heap Java comum e esses argumentos são configurados o espaço para esse espaço de heap Java regular. No entanto, existem argumentos semelhantes que podem ser usados (pelo menos com as jvms Sun / OpenJDK) para aumentar o tamanho da pilha de geração permanente:
O padrão é 64m.
2) Ativar varredura
Outra maneira de cuidar disso para sempre é permitir que as classes sejam descarregadas para que seu PermGen nunca acabe:
Coisas assim funcionaram para mim no passado. Porém, há uma troca significativa de desempenho ao usá-las, pois as permgen sweeps farão 2 pedidos extras para cada solicitação que você fizer ou algo nesse sentido. Você precisará equilibrar seu uso com as compensações.
Você pode encontrar os detalhes desse erro.
http://faisalbhagat.blogspot.com/2014/09/java-outofmemoryerror-permgen.html
fonte
Como alternativa, você pode mudar para o JRockit, que manipula permgen de maneira diferente da jvm da sun. Geralmente, também apresenta melhor desempenho.
http://www.oracle.com/technetwork/middleware/jrockit/overview/index.html
fonte
java.lang.OutOfMemoryError: There is insufficient native memory
.Eu tive o problema de que estamos falando aqui, meu cenário é eclipse-helios + tomcat + jsf e o que você estava fazendo é implantar um aplicativo simples no tomcat. Eu estava mostrando o mesmo problema aqui, resolvi-o da seguinte forma.
No eclipse, vá para a guia servidores, clique duas vezes no servidor registrado no meu caso, o tomcat 7.0, abre as informações gerais de registro do servidor de arquivos. Na seção "Informações gerais", clique no link "Abrir configuração de inicialização" , isso abre a execução das opções do servidor na guia Argumentos nos argumentos da VM adicionados no final dessas duas entradas
E pronto.
fonte
A resposta mais simples hoje em dia é usar o Java 8.
Ele não reserva mais memória exclusivamente para o espaço PermGen, permitindo que a memória PermGen seja combinada com o conjunto de memórias regular.
Lembre-se de que você precisará remover todos os
-XXPermGen...=...
parâmetros de inicialização não-padrão da JVM se não desejar que o Java 8 reclame que eles não fazem nada.fonte
Na área de texto Opções de Java, anexe esta linha:
fonte
O erro de espaço de geração de permissão ocorre devido ao uso de espaço grande, em vez do espaço fornecido pela jvm para executar o código.
A melhor solução para esse problema nos sistemas operacionais UNIX é alterar algumas configurações no arquivo bash. Os passos seguintes resolvem o problema.
Execute o comando
gedit .bashrc
no terminal.Crie
JAVA_OTPS
variável com o seguinte valor:Salve o arquivo bash. Execute o comando exec bash no terminal. Reinicie o servidor.
Espero que essa abordagem funcione no seu problema. Se você usa uma versão Java menor que 8, esse problema ocorre algumas vezes. Mas se você usa o Java 8, o problema nunca ocorre.
fonte
Aumentar o tamanho da geração permanente ou ajustar os parâmetros do GC NÃO ajudará se você tiver um vazamento de memória real. Se seu aplicativo ou alguma biblioteca de terceiros que ele usa, vaza carregadores de classes, a única solução real e permanente é encontrar esse vazamento e corrigi-lo. Existem várias ferramentas que podem ajudá-lo, uma das recentes é a Plumbr , que acaba de lançar uma nova versão com os recursos necessários.
fonte
Além disso, se você estiver usando o log4j em seu aplicativo da web, verifique este parágrafo na documentação do log4j .
Parece que, se você estiver usando
PropertyConfigurator.configureAndWatch("log4j.properties")
, causará vazamento de memória ao remover o aplicativo da web.fonte
Eu tenho uma combinação de Hibernate + Eclipse RCP, tentei usar
-XX:MaxPermSize=512m
e-XX:PermSize=512m
e parece estar a trabalhar para mim.fonte
Set
-XX:PermSize=64m -XX:MaxPermSize=128m
. Mais tarde, você também pode tentar aumentarMaxPermSize
. Espero que funcione. O mesmo funciona para mim. Definir apenasMaxPermSize
não funcionou para mim.fonte
Eu tentei várias respostas e a única coisa que finalmente fez o trabalho foi essa configuração para o plugin do compilador no pom:
espero que este ajude.
fonte
jrockitresolveu isso para mim também; no entanto, notei que os tempos de reinicialização do servlet eram muito piores, portanto, embora tenha sido melhor na produção, foi uma espécie de empecilho no desenvolvimento.
fonte
A configuração da memória depende da natureza do seu aplicativo.
O que você está fazendo?
Qual é a quantidade de transações pré-processadas?
Quantos dados você está carregando?
etc.
etc.
etc
Provavelmente, você pode criar um perfil do seu aplicativo e começar a limpar alguns módulos dele.
O Tomcat possui implantação a quente, mas consome memória. Tente reiniciar seu contêiner de vez em quando. Além disso, você precisará saber a quantidade de memória necessária para executar no modo de produção; esse é um bom momento para essa pesquisa.
fonte
Eles dizem que a versão mais recente do Tomcat (6.0.28 ou 6.0.29) lida com a tarefa de reimplementar servlets muito melhor.
fonte
Eu me deparo exatamente com o mesmo problema, mas infelizmente nenhuma das soluções sugeridas realmente funcionou para mim. O problema não ocorreu durante a implantação, e eu não estava realizando nenhuma implantação quente.
No meu caso, o problema ocorreu todas as vezes no mesmo ponto durante a execução do meu aplicativo da web, enquanto eu estava conectado (via hibernação) ao banco de dados.
Esse link (também mencionado anteriormente) forneceu informações internas suficientes para resolver o problema. Mover o driver jdbc- (mysql) para fora do WEB-INF e para a pasta jre / lib / ext / parece ter resolvido o problema. Essa não é a solução ideal, pois a atualização para um JRE mais recente exigiria a reinstalação do driver. Outro candidato que pode causar problemas semelhantes é o log4j; portanto, você também pode mover esse
fonte
O primeiro passo nesse caso é verificar se o GC tem permissão para descarregar classes do PermGen. A JVM padrão é bastante conservadora a esse respeito - as classes nascem para viver para sempre. Portanto, uma vez carregadas, as classes permanecem na memória, mesmo que nenhum código as esteja usando. Isso pode se tornar um problema quando o aplicativo cria muitas classes dinamicamente e as classes geradas não são necessárias por períodos mais longos. Nesse caso, permitir que a JVM descarregue definições de classe pode ser útil. Isso pode ser alcançado adicionando apenas um parâmetro de configuração aos seus scripts de inicialização:
Por padrão, isso é definido como false e, para habilitá-lo, você precisa definir explicitamente a seguinte opção nas opções Java. Se você ativar CMSClassUnloadingEnabled, o GC também varrerá o PermGen e removerá as classes que não são mais usadas. Lembre-se de que esta opção funcionará apenas quando o UseConcMarkSweepGC também estiver ativado usando a opção abaixo. Portanto, ao executar o ParallelGC ou, se Deus não permitir, o GC serial, verifique se você configurou o GC para CMS especificando:
fonte
Atribuir mais memória ao Tomcat NÃO é a solução adequada.
A solução correta é fazer uma limpeza após o contexto ser destruído e recriado (a implantação a quente). A solução é parar o vazamento de memória.
Se o servidor Tomcat / Webapp estiver informando que você não conseguiu registrar os drivers (JDBC), cancele o registro deles. Isso interromperá o vazamento de memória.
Você pode criar um ServletContextListener e configurá-lo em seu web.xml. Aqui está um exemplo ServletContextListener:
E aqui você o configura no seu web.xml:
fonte
"Eles" estão errados porque estou executando o 6.0.29 e tenho o mesmo problema, mesmo depois de definir todas as opções. Como Tim Howland disse acima, essas opções apenas adiam o inevitável. Eles permitem que eu reimplante três vezes antes de atingir o erro, em vez de cada vez que reimplantar.
fonte
Caso você esteja obtendo isso no IDE do eclipse, mesmo depois de definir os parâmetros
--launcher.XXMaxPermSize
,-XX:MaxPermSize
etc, ainda assim, se estiver recebendo o mesmo erro, é mais provável que o eclipse esteja usando uma versão com erros do JRE que teria sido instalada por alguns aplicativos de terceiros e definido como padrão. Essas versões de buggy não capturam os parâmetros PermSize e, não importa o que você definir, você continuará recebendo esses erros de memória. Portanto, no seu eclipse.ini, adicione os seguintes parâmetros:Certifique-se também de definir o JRE padrão nas preferências no eclipse para a versão correta do java.
fonte
A única maneira que funcionou para mim foi com o JRockit JVM. Eu tenho o MyEclipse 8.6.
O heap da JVM armazena todos os objetos gerados por um programa Java em execução. Java usa o
new
operador para criar objetos, e a memória para novos objetos é alocada no heap em tempo de execução. A coleta de lixo é o mecanismo de liberar automaticamente a memória contida nos objetos que não são mais referenciados pelo programa.fonte
Eu estava tendo um problema semelhante. O meu é o projeto baseado em injeção de dependência JDK 7 + Maven 3.0.2 + Struts 2.0 + Google GUICE.
Sempre que eu tentava executar o
mvn clean package
comando, ele mostrava o seguinte erro e ocorria "BUILD FAILURE"Eu tentei todas as dicas e truques úteis acima, mas infelizmente nenhum funcionou para mim. O que funcionou para mim é descrito passo a passo abaixo: =>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
elemento e, em seguida,<argLine>
subelemento no qual passa-Xmx512m -XX:MaxPermSize=256m
como mostrado abaixo =><configuration> <argLine>-Xmx512m -XX:MaxPermSize=256m</argLine> </configuration>
Espero que ajude, feliz programação :)
fonte