Como lidar com "java.lang.OutOfMemoryError: Java heap space" erro?

Estou a escrever uma aplicação do lado do cliente Swing (designer gráfico de fontes) em **Java 5***. Recentemente, eu estou encontrando java.lang.OutOfMemoryError: erro "Java heap space" porque não estou a ser conservador no 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 Máquina Virtual Java 5.0][1] e outros dizendo na máquina Windows que o tamanho máximo do heap JVM padrão é64MB`.

Dada esta situação, como devo lidar com este constrangimento?

Eu poderia aumentar o max heap size usando a opção command line para java, mas isso exigiria descobrir a RAM disponível e escrever algum programa de lançamento ou roteiro. Além disso, aumentar para algum finito máximo não ultimamente livrar-se do problema.

Eu poderia reescrever alguns dos meus códigos para persistir objetos no sistema de arquivos frequentemente (usar banco de dados é a mesma coisa) para liberar a memória. Poderia funcionar, mas provavelmente's também funciona muito bem.

Se você pudesse me apontar detalhes das idéias acima ou algumas alternativas como memória virtual automática, ampliando dinamicamente o tamanho da pilha, isso seria ótimo.

Solução

Em última análise, você sempre tem um máximo finito de pilha para usar, não importa em que plataforma você esteja rodando. No Windows 32 bit isto é cerca de 2GB (não especificamente heap, mas a quantidade total de memória por processo). Acontece que o Java escolhe fazer o padrão menor (presumivelmente para que o programador possa't criar programas que tenham alocação de memória em execução sem correr para este problema e ter que examinar exatamente o que eles estão fazendo).

Portanto, isto dado que existem várias abordagens que você poderia tomar para determinar que quantidade de memória você precisa ou para reduzir a quantidade de memória que você está usando. Um erro comum com linguagens de coleta de lixo como Java ou C# é manter referências a objetos que você não mais estão usando, ou alocar muitos objetos quando você poderia reusá-los em seu lugar. Enquanto os objetos tiverem uma referência a eles, eles continuarão a usar o espaço de pilha de lixo, pois o coletor de lixo não os apagará.

Neste caso você pode usar um profiler de memória Java para determinar que métodos em seu programa estão alocando um grande número de objetos e então determinar se há uma maneira de garantir que eles não sejam mais referenciados, ou para não alocá-los em primeiro lugar. Uma opção que usei no passado foi "JMP" .

Se você determinar que está alocando esses objetos por um motivo e precisar manter em torno de referências (dependendo do que estiver fazendo isso pode ser o caso), você só precisará aumentar o tamanho máximo da pilha quando iniciar o programa. No entanto, uma vez que você faça o perfil da memória e entenda como seus objetos estão sendo alocados, você deve ter uma idéia melhor sobre quanta memória você precisa.

Em geral se você pode't garantir que seu programa será executado em alguma quantidade finita de memória (talvez dependendo do tamanho da entrada) você sempre terá esse problema. Só depois de esgotar tudo isto é que precisará de procurar objectos em cache no disco, etc. Neste ponto você deve ter uma boa razão para dizer "Eu preciso do Xgb de memória" para algo e você pode't trabalhar em torno dele melhorando seus algoritmos ou padrões de alocação de memória. Geralmente este só será o caso para algoritmos que operam em grandes conjuntos de dados (como uma base de dados ou algum programa de análise científica) e então técnicas como caching e IO mapeado de memória se tornam úteis.

Comentários (1)

Execute Java com a opção de linha de comando -Xmx, que define o tamanho maximum da pilha.

Veja aqui para detalhes.

Comentários (3)

Sim, com o -Xmx você pode configurar mais memória para a sua JVM. Para ter certeza de que você não'não vaza ou desperdiça memória. Pegue um heap dump e use o Eclipse Memory Analyzer para analisar o seu consumo de memória.

Comentários (1)