Estou escrevendo um aplicativo Swing do lado do cliente (designer de fonte gráfica) em Java 5 . Recentemente, estou tendo java.lang.OutOfMemoryError: Java heap space
erro porque não estou sendo conservador quanto ao uso de memória. O usuário pode abrir um número ilimitado de arquivos, e o programa mantém os objetos abertos na memória. Após uma rápida pesquisa, encontrei Ergonomia na Java Virtual Machine 5.0 e outros disseram na máquina Windows que a JVM padroniza o tamanho máximo de heap como 64MB
.
Diante dessa situação, como devo lidar com essa restrição?
Eu poderia aumentar o tamanho máximo do heap usando a opção de linha de comando para java, mas isso exigiria descobrir a RAM disponível e escrever algum programa ou script de inicialização. Além disso, aumentar para um máximo finito não acaba com o problema.
Eu poderia reescrever parte do meu código para persistir objetos no sistema de arquivos com freqüência (usar o banco de dados é a mesma coisa) para liberar a memória. Pode funcionar, mas provavelmente também é muito trabalhoso.
Se você puder me indicar detalhes das idéias acima ou algumas alternativas, como memória virtual automática, estender o tamanho da pilha dinamicamente , isso será ótimo.
fonte
Respostas:
Por fim, você sempre tem um máximo finito de heap para usar, independentemente da plataforma em que está executando. No Windows 32 bits, isso ocorre em torno de
2GB
(não especificamente na pilha, mas na quantidade total de memória por processo). Ocorre que o Java escolhe diminuir o padrão (presumivelmente para que o programador não possa criar programas que tenham alocação de memória descontrolada sem enfrentar esse problema e ter que examinar exatamente o que está fazendo).Sendo assim, existem várias abordagens que você pode adotar para determinar a quantidade de memória necessária ou reduzir a quantidade de memória que está usando. Um erro comum nas linguagens de coleta de lixo, como Java ou C #, é manter referências de objetos que você não está mais usando ou alocar muitos objetos quando você pode reutilizá- los. Desde que os objetos tenham uma referência a eles, eles continuarão a usar o espaço de heap, pois o coletor de lixo não os excluirá.
Nesse caso, você pode usar um criador de perfil de memória Java para determinar quais métodos em seu programa estão alocando um grande número de objetos e, em seguida, determinar se existe uma maneira de garantir que eles não sejam mais referenciados ou para não alocá-los em primeiro lugar. Uma opção que eu usei no passado é "JMP" http://www.khelekore.org/jmp/ .
Se você determinar que está alocando esses objetos por um motivo e precisar manter as referências (dependendo do que estiver fazendo, pode ser o caso), precisará aumentar o tamanho máximo do heap ao iniciar o programa. No entanto, depois de fazer o perfil da memória e entender como seus objetos estão sendo alocados, você deve ter uma idéia melhor sobre a quantidade de memória necessária.
Em geral, se você não pode garantir que seu programa será executado em uma quantidade finita de memória (talvez dependendo do tamanho da entrada), você sempre encontrará esse problema. Somente depois de esgotar tudo isso, você precisará examinar os objetos em cache no disco, etc. Nesse momento, você deve ter um bom motivo para dizer "Preciso de Xgb de memória" para algo e não conseguirá solucionar isso melhorando seus algoritmos ou padrões de alocação de memória. Geralmente, isso geralmente acontece apenas com algoritmos que operam em grandes conjuntos de dados (como um banco de dados ou algum programa de análise científica) e, em seguida, técnicas como cache e E / S mapeadas na memória se tornam úteis.
fonte
Execute o Java com a opção de linha de comando
-Xmx
, que define o tamanho máximo da pilha.Veja aqui para detalhes .
fonte
Você pode especificar por projeto quanto espaço de heap seu projeto deseja
A seguir, é apresentado o Eclipse Helios / Juno / Kepler :
Clique com o botão direito do mouse em
então adicione isso
fonte
Aumentar o tamanho do heap não é uma "correção", é um "gesso", 100% temporário. Ele irá travar novamente em outro lugar. Para evitar esses problemas, escreva código de alto desempenho.
fonte
Uma grande ressalva ---- no meu escritório, estávamos descobrindo que (em algumas máquinas Windows) não era possível alocar mais de 512m para o heap Java. Isso aconteceu devido ao produto antivírus Kaspersky instalado em algumas dessas máquinas. Depois de desinstalar o produto AV, descobrimos que poderíamos alocar pelo menos 1,6 GB, ou seja,
-Xmx1600m
(m é obrigatório, caso contrário, isso levará a outro erro "Heap inicial muito pequeno").Não faço ideia se isso acontece com outros produtos AV, mas presumivelmente isso está acontecendo porque o programa AV está reservando um pequeno bloco de memória em todos os espaços de endereço, impedindo, assim, uma única alocação muito grande.
fonte
Os argumentos da VM funcionaram para mim no eclipse. Se você estiver usando o eclipse versão 3.4, faça o seguinte
vá para
Run --> Run Configurations -->
selecionar o projeto em maven build -> selecione a guia "JRE" -> e digite-Xmx1024m
.Como alternativa, você pode
Run --> Run Configurations --> select the "JRE" tab -->
digitar -Xmx1024m
Isso deve aumentar a pilha de memória para todas as compilações / projetos. O tamanho da memória acima é de 1 GB. Você pode otimizar da maneira que desejar.
fonte
Sim,
-Xmx
você pode configurar mais memória para sua JVM. Para garantir que você não vaze ou desperdice memória. Faça um despejo de pilha e use o Eclipse Memory Analyzer para analisar seu consumo de memória.fonte
Gostaria de adicionar recomendações da resolução de problemas da oracle artigo sobre .
Exceção no encadeamento thread_name: java.lang.OutOfMemoryError: espaço de heap Java
Causas Possíveis:
Problema de configuração simples , em que o tamanho de heap especificado é insuficiente para o aplicativo.
O aplicativo não intencionalmente mantém referências a objetos , e isso evita que os objetos sejam coletados no lixo.
Uso excessivo de finalizadores .
Após a coleta de lixo , os objetos são enfileirados para finalização , o que ocorre posteriormente. os finalizadores são executados por um encadeamento daemon que atende à fila de finalização. Se o encadeamento do finalizador não puder acompanhar a fila de finalização, o heap Java poderá ser preenchido e esse tipo de exceção OutOfMemoryError será acionado.
Um cenário que pode causar essa situação é quando um aplicativo cria encadeamentos de alta prioridade que fazem com que a fila de finalização aumente a uma taxa mais rápida que a taxa na qual o encadeamento do finalizador está atendendo a essa fila.
fonte
Siga as etapas abaixo:
Aberto
catalina.sh
do tomcat / bin.Altere JAVA_OPTS para
Reinicie seu tomcat
fonte
Eu li em outro lugar que você pode tentar - pegar java.lang.OutOfMemoryError e no bloco catch, você pode liberar todos os recursos que você sabe que podem usar muita memória, fechar conexões e assim por diante.
System.gc()
depois tentar novamente o que quer que seja você ia fazer.Outra maneira é essa, embora eu não saiba se isso funcionaria, mas atualmente estou testando se funcionará no meu aplicativo.
A idéia é fazer a coleta de lixo chamando System.gc (), conhecido por aumentar a memória livre. Você pode continuar verificando isso após a execução de um código de consumo de memória.
fonte
A maneira mais fácil de resolver
OutOfMemoryError
em java é aumentar o tamanho máximo de heap usando as opções da JVM-Xmx512M
; isso resolverá imediatamente seu OutOfMemoryError. Esta é a minha solução preferida quando obtenho o OutOfMemoryError no Eclipse, Maven ou ANT durante a criação do projeto, porque com base no tamanho do projeto, você pode facilmente ficar sem memória.Aqui está um exemplo de aumento do tamanho máximo de heap da JVM. Também é melhor manter a proporção de -Xmx para -Xms 1: 1 ou 1: 1,5 se você estiver configurando o tamanho de heap no aplicativo java.
export JVM_ARGS="-Xms1024m -Xmx1024m"
Link de referência
fonte
Por padrão para desenvolvimento, a JVM usa tamanho pequeno e configuração pequena para outros recursos relacionados ao desempenho. Mas para produção, você pode ajustar, por exemplo (além disso, pode existir uma configuração específica do servidor de aplicativos) -> (se ainda não houver memória suficiente para atender à solicitação e o heap já tiver atingido o tamanho máximo, ocorrerá um OutOfMemoryError)
Por exemplo: No linux Platform, configurações preferenciais do modo de produção.
Depois de baixar e configurar o servidor dessa maneira, http://www.ehowstuff.com/how-to-install-and-setup-apache-tomcat-8-on-centos-7-1-rhel-7/
1.crie o arquivo setenv.sh na pasta / opt / tomcat / bin /
2.Abra e escreva esses parâmetros para definir o modo preferencial.
3)
service tomcat restart
fonte
Eu enfrentei o mesmo problema do tamanho da pilha de java.
Eu tenho duas soluções, se você estiver usando o java 5 (1.5).
basta instalar o jdk1.6 e acessar as preferências do eclipse e definir o caminho do jre do jav1 1.6 como você instalou.
Verifique o argumento da sua VM e deixe que seja o que for. basta adicionar uma linha abaixo de todos os argumentos presentes nos argumentos da VM como -Xms512m -Xmx512m -XX: MaxPermSize = ... m (192m).
Eu acho que vai funcionar ...
fonte
Se você precisar monitorar o uso da memória em tempo de execução, o
java.lang.management
pacote ofereceMBeans
que pode ser usado para monitorar os conjuntos de memórias na sua VM (por exemplo, espaço eden, geração protegida etc.) e também o comportamento da coleta de lixo.O espaço livre de heap relatado por esses MBeans variará bastante, dependendo do comportamento do GC, principalmente se o aplicativo gerar muitos objetos posteriormente editados pelo GC. Uma abordagem possível é monitorar o espaço de heap livre após cada GC completo, que você pode usar para tomar uma decisão sobre a liberação de memória persistindo por objetos.
Por fim, sua melhor aposta é limitar a retenção de memória o máximo possível, enquanto o desempenho permanece aceitável. Como um comentário anterior observou, a memória é sempre limitada, mas seu aplicativo deve ter uma estratégia para lidar com o esgotamento da memória.
fonte
Observe que, se você precisar disso em uma situação de implementação, considere usar o Java WebStart (com uma versão "ondisk", não a rede - possível no Java 6u10 e posterior), pois permite especificar os vários argumentos para a JVM em uma cruz caminho da plataforma.
Caso contrário, você precisará de um iniciador específico do sistema operacional que defina os argumentos necessários.
fonte
Se esse problema estiver ocorrendo no Wildfly 8 e no JDK1.8, precisamos especificar as configurações do MaxMetaSpace em vez das configurações do PermGen.
Por exemplo, precisamos adicionar a configuração abaixo no arquivo setenv.sh do wildfly.
JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M"
Para mais informações, consulte Wildfly Heap Issue
fonte
Em relação ao netbeans, você pode definir o tamanho máximo de heap para resolver o problema.
Vá para 'Executar', depois -> 'Definir configuração do projeto' -> 'Personalizar' -> 'executar' da janela exibida -> 'Opção da VM' -> preencha '-Xms2048m -Xmx2048m' .
fonte
Se você continuar alocando e mantendo referências a objetos, preencherá toda a quantidade de memória que tiver.
Uma opção é fechar e abrir um arquivo transparente quando eles alternam as guias (você mantém apenas um ponteiro para o arquivo, e quando o usuário alterna a guia, você fecha e limpa todos os objetos ... isso fará com que o arquivo mude mais lentamente ... mas ...) e talvez mantenha apenas 3 ou 4 arquivos na memória.
Outra coisa que você deve fazer é, quando o usuário abrir um arquivo, carregá-lo e interceptar qualquer OutOfMemoryError, então (como não é possível abrir o arquivo) feche esse arquivo, limpe seus objetos e avise o usuário que ele deve fechar sem uso arquivos.
Sua idéia de estender dinamicamente a memória virtual não resolve o problema, pois a máquina é limitada em recursos; portanto, você deve ter cuidado e lidar com problemas de memória (ou pelo menos, ter cuidado com eles).
Algumas dicas que eu vi com vazamentos de memória são:
-> Lembre-se de que se você colocar algo em uma coleção e depois esquecê-la, você ainda terá uma forte referência a ela; portanto, anule a coleção, limpe-a ou faça algo com ela ... caso contrário, você encontrará um vazamento de memória difícil de encontrar.
-> Talvez, o uso de coleções com referências fracas (fracohashmap ...) possa ajudar com problemas de memória, mas você deve ter cuidado com isso, pois pode achar que o objeto que procura foi coletado.
-> Outra idéia que encontrei é desenvolver uma coleção persistente que é armazenada nos objetos de banco de dados menos usados e carregados de forma transparente. Essa provavelmente seria a melhor abordagem ...
fonte
Se tudo mais falhar, além de aumentar o tamanho máximo da pilha, tente também aumentar o tamanho da troca. Para Linux, a partir de agora, instruções relevantes podem ser encontradas em https://linuxize.com/post/create-a-linux-swap-file/ .
Isso pode ajudar se você estiver, por exemplo, compilando algo grande em uma plataforma incorporada.
fonte