Salve galera,
tenho uma missão de manipular em java matrizes muito grande. Estas matrizes são tão grandes que setei na hora de compilar: “java -Xms512m -Xmx1600m nome_da_classe” . E mesmo assim, ocorre a exceção: “Exception in thread “main” java.lang.OutOfMemoryError: Java heap space”.
Tentei aumentar a faixa de memória para Marquina Virtual java, mas ocorre a seguinte mensagem : “Could not reserve enough space for object heap”.
O que eu faço agora, para aumentar essa faixa de memoria para JVM?
Você tá usando windows xp, adivinhei? Você tem basicamente 3 opções:
Usa uma JVM 64bits.
Usa windows 2003 configurado pra user-space de 3Giga.
Usa linux configurado pra user-space de 3Giga.
O windows 32bits não deixa um processo sozinho alocar mais de 2gigas de memória, isso é um limite do design do SO.
Em algum lugar do Bug Database da Sun, eles mencionam que -Xmx aceita no máximo por volta de 1400M no ambiente Windows (32 bits), porque é necessário alocar uma área contígua de memória no heap, e o Windows, mesmo usando a opção de 3G, não consegue alocar uma área maior que essa (e acho que um problema semelhante ocorre no Linux 32 bits, só que com 1800M mais ou menos). Você pode fazer alguma das seguintes coisas:
Use uma precisão menor (double = 2X float) nas matrizes maiores - sei que, dependendo do seu problema, você não pode fazer isso
Use uma JVM, um sistema operacional de 64 bits, e um processador adequados para 64 bits
Dependendo do seu Linux, isso já está feito.
Em algumas distribuições, é necessário efetuar o boot com outro kernel - muitas distribuições dão várias opçoes durante o boot para usar um determinado kernel, mais apropriado para a sua situação.
Veja com o pessoal que é fera na sua distribuição do Linux o que você deve fazer.
Não sei se isso serve, mas você, por acaso, não poderia manipular essas matrizes em arquivo?
Já tivemos um caso num sistema aqui em que o resultado de uma consulta era gigantesco, então, foi contruído uma inteligência para “mapear” o resultset em arquivos com capacidade limitada de 1000 registros (não me lembro bem se é essa a quantidade) e a leitura era feita nesses arquivos.
E olha que não degradou tanto assim a performance.
A idéia de mapear a matriz em arquivo parece ser boa mesmo. Como ficaria esse mapeamento usando NIO? Dá uma olhada aí pra ver, já que a NIO oferece métodos de alto desempenho para acesso à arquivos.
Já utilizei NIO em alguns projetos e o ganho de performance é brutal!
O problema do NIO, se você for usar arquivos mapeados em memória, é justamente a parte de memória virtual. Talvez você não possa usar um arquivo maior que 2GB, ou um pouco menos. É questão de testar
Você deve ter uma versão do Windows que permita isso (usualmente Windows 2003 Enterprise), e no boot.ini deve haver uma opção /3G ou coisa parecida. Mesmo assim, há poucos programas que conseguem reconhecer o espaço de endereçamento adicional (tal como o MS SQL Server Enterprise Edition); o Java da Sun não consegue enxergar o espaço de endereçamento adicional.
Consulte a documentação da sua versão do Windows em technet.microsoft.com ou msdn.microsoft.com.
Pode ser que você simplesmente não consiga habilitar os tais 3 GB de jeito nenhum (exemplo: Windows XP não permite isso).
Se sua máquina for suficientemente nova (Pentium D, Core 2 Duo, Athlon 64 etc), você pode usar uma distribuição do Linux para 64 bits, ou um Windows (Vista, 2003, 2008) de 64 bits.