Pergunta

Estou recebendo o seguinte erro na execução de um programa multithreading

java.lang.OutOfMemoryError: Java heap space

O erro acima ocorreu em um dos threads.

  1. Até onde sei, o espaço Heap é ocupado apenas por variáveis ​​de instância.Se isso estiver correto, então por que esse erro ocorreu depois de funcionar bem por algum tempo, já que o espaço para variáveis ​​de instância é alocado no momento da criação do objeto.

  2. Existe alguma maneira de aumentar o espaço de heap?

  3. Que alterações devo fazer em meu programa para que ele ocupe menos espaço de heap?

Foi útil?

Solução

Se você quiser aumentar seu espaço de heap, você pode usar java -Xms<initial heap size> -Xmx<maximum heap size> na linha de comando.Por padrão, os valores são baseados na versão do JRE e na configuração do sistema.Você pode descobrir mais sobre as opções de VM no site Java.

No entanto, eu recomendaria criar um perfil de seu aplicativo para descobrir por que o tamanho do seu heap está sendo consumido.O NetBeans tem um muito bom perfilador incluído com ele.Acredito que use o jvisualvm sob o capô.Com um criador de perfil, você pode tentar descobrir onde muitos objetos estão sendo criados, quando os objetos são coletados como lixo e muito mais.

Outras dicas

1.- Sim, mas refere-se basicamente a toda a memória utilizada pelo seu programa.

2.- Sim, veja as opções do Java VM

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size

Ou seja

java -Xmx2g atribua no máximo 2 gigabytes de RAM ao seu aplicativo

Mas você deve primeiro ver se não há vazamento de memória.

3.- Depende do programa.Experimente vazamentos de memória pontual.Esta pergunta seria muito difícil de responder.Ultimamente você pode criar perfis usando JConsole para tentar descobrir para onde está indo sua memória

Você pode consultar este site para saber mais sobre memória na JVM:http://developer.streamezzo.com/content/learn/articles/optimization-heap-memory-usage

Achei útil usar visualgc para observar como as diferentes partes do modelo de memória estão sendo preenchidas, para determinar o que mudar.

É difícil determinar qual parte da memória foi preenchida, portanto, visualgc, pois você pode querer apenas alterar a parte que está com problema, em vez de apenas dizer,

Multar!Darei 1G de RAM para a JVM.

Tente ser mais preciso sobre o que você está fazendo, no longo prazo você provavelmente achará o programa melhor para isso.

Para determinar onde pode estar o vazamento de memória, você pode usar testes de unidade para isso, testando qual era a memória antes e depois do teste, e se houver uma mudança muito grande, você pode querer examiná-la, mas você precisa faça a verificação enquanto seu teste ainda está em execução.

Para aumentar o tamanho do heap você pode usar o argumento -Xmx ao iniciar o Java;por exemplo.

-Xmx256M

Você pode obter o tamanho da memória heap por meio do programa abaixo.

public class GetHeapSize {
    public static void main(String[] args) {
        long heapsize = Runtime.getRuntime().totalMemory();
        System.out.println("heapsize is :: " + heapsize);
    }
} 

então, você também pode aumentar o tamanho do heap usando:java -Xmx2ghttp://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

  1. Até onde sei, o espaço Heap é ocupado apenas por variáveis ​​de instância.Se isso estiver correto, então por que esse erro ocorreu depois de funcionar bem por algum tempo, já que o espaço para variáveis ​​de instância é alocado no momento da criação do objeto.

Isso significa que você está criando mais objetos em seu aplicativo continuamente durante um período de tempo.Novos objetos serão armazenados na memória heap e essa é a razão do crescimento da memória heap.

Heap não contém apenas variáveis ​​de instância.Ele armazenará todos os tipos de dados não primitivos (Objetos).A vida útil desses objetos pode ser curta (bloco de método) ou longa (até que o objeto seja referenciado em sua aplicação)

  1. Existe alguma maneira de aumentar o espaço de heap?

Sim.Dê uma olhada neste oráculo artigo para mais detalhes.

Existem dois parâmetros para definir o tamanho do heap:

-Xms:, que define o tamanho de heap inicial e mínimo

-Xmx:, que define o tamanho máximo de heap

  1. Que alterações devo fazer em meu programa para que ele ocupe menos espaço de heap?

Depende da sua aplicação.

  1. Defina a memória heap máxima de acordo com os requisitos do seu aplicativo

  2. Não cause vazamentos de memória em seu aplicativo

  3. Se você encontrar vazamentos de memória em seu aplicativo, encontre a causa raiz com a ajuda de ferramentas de criação de perfil como ESTEIRA, VM visual , jconsole etc.Depois de encontrar a causa raiz, corrija os vazamentos.

Notas importantes da Oracle artigo

Causa:A mensagem detalhada do espaço de heap Java indica que o objeto não pôde ser alocado no heap Java.Este erro não implica necessariamente um vazamento de memória.

Razões possíveis:

  1. Configuração inadequada (não alocando memória suficiente)
  2. O aplicativo está retendo involuntariamente referências a objetos e isso evita que os objetos sejam coletados como lixo
  3. Aplicativos que fazem uso excessivo de finalizadores.Se uma classe tiver um método finalize, então os objetos desse tipo não terão seu espaço recuperado no momento da coleta de lixo. Se o encadeamento do finalizador não conseguir acompanhar a fila de finalização, o heap Java poderá ficar cheio e esse tipo de exceção OutOfMemoryError será lançada.

Por outro lado, use algoritmos melhores de coleta de lixo ( CMS ou G1GC)

Veja isso pergunta para entender o G1GC

  1. Na maioria dos casos, o código não está otimizado.Libere aqueles objetos que você acha que não serão mais necessários.Evite a criação de objetos em seu loop todas as vezes.Tente usar caches.Não sei como está seu aplicativo.Mas na programação, uma regra da vida normal também se aplica

    Prevenção é melhor que a cura."Não crie objetos desnecessários"

  1. As variáveis ​​locais estão localizadas na pilha.O espaço de heap é ocupado por objetos.

  2. Você pode usar o -Xmx opção.

  3. Basicamente, o espaço de heap é usado toda vez que você aloca um novo objeto com new e liberado algum tempo depois que o objeto não for mais referenciado.Portanto, certifique-se de não manter referências a objetos que não precisa mais.

Não, acho que você está pensando no espaço da pilha.O espaço de heap é ocupado por objetos.A forma de aumentá-lo é -Xmx256m, substituindo 256 pela quantidade necessária na linha de comando.

No netbeans, vá para a barra de ferramentas 'Executar', -> 'Definir configuração do projeto' -> 'Personalizar' -> 'executar' da janela exibida -> 'Opção de VM' -> preencha '-Xms2048m -Xmx2048m'.Isso poderia resolver o problema do tamanho do heap.

Para evitar essa exceção, se você estiver usando JUnit e Spring, tente adicionar isto em todas as classes de teste:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top