OutOfMemory: java não está consumindo toda a memória disponível

1 resposta
Decio_Luckow

Bom dia,

Eu estou tendo alguns problemas de outofmemory no produto que dou manutenção. Já que quando ocorre o outofmemory todo o aplicativo (web) para de funcionar eu gostaria de tentar evitar que ocorra o estouro.

O estouro de memória é causado por um processamento muito grande de informações, solicitado pelo usuário. Eu não tenho como limitar esta quantidade via sistema, pois daih eu estaria processando um resultado incompleto.

Para isso desenvolvi um algoritmo que identifica o percentual de memória utilizada e interrompe os processamentos mais pesados antes que ocorra o estouro. Coloquei como limite 95% da memória consumida.
quando ocorre o estouro de memória, solito ao usuário que diminua o escopo da pesquisa.

Em window isto estava funcionando legal, mas quando fui testar em linux/unix percebi que a memória já estourava quando atingia 55% em uma máquina linux e 68% em uma máquina linux 64bit. Em windows pode chegar a 80%

Antes de continuar, a pergunta é? Porque isto está acontecendo, se vocês já passaram por isso o que posso fazer para o Java consumir toda a memória disponível

Atualmente estou executando alguns testes e tenho o seguinte resultado quando ocorre o estouro, em uma máquina WinXP com Xmx de 512

Memoria maxima: 499.5
Memoria alocada: 499.5
Memoria usada: 321.7482452392578
Memoria livre: 177.7517547607422
Percentual consumido: 64 %

A linha de execução pode ser: java -Xmx512m EstouraMemoria

A minha classe de teste é a seguinte:

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class EstouraMemoria {

  private static double getPercentual() {
    return (((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) * 100) / Runtime.getRuntime().maxMemory());
  }

  /**
   * @param args
   * @throws IOException 
   */
  public static void main(String[] args) throws IOException {

    String modelo = null;
    for (int i = 0; i < 25; i++) {
      modelo += "asdfasdfasfasdfasdasdfasdfasfasdfasdasdfasdfasfasdfasdasdfasdfasfasdfasdasdfasdfasfas";
    }

    StringBuffer texto = new StringBuffer(modelo);

    while (true) {

      texto.append(modelo);
      System.out.println("Memoria maxima: " + (Runtime.getRuntime().maxMemory() / 1024d / 1024d));
      System.out.println("Memoria alocada: " + ((Runtime.getRuntime().totalMemory()) / 1024d / 1024d));
      System.out.println("Memoria usada: " + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024d / 1024d));
      System.out.println("Memoria livre: " + (Runtime.getRuntime().freeMemory() / 1024d / 1024d));
      System.out.println("Percentual consumido: " + getPercentual());
      System.out.println("-------------------------------");

      if (getPercentual() > 90) {
        System.out.println("#####################################");
        System.out.println("VAI ESTOURAR");
        System.out.println("#####################################");
      }
    }
  }
}

1 Resposta

fabaugsilv

Acho que você deveria repensar nesse seu processo que executa uma enorme quantidade de dados, não dá para você processar um pouco enviar para o usuário, processar mais um pouco e enviar para o usuário, paginando o resultado ou se não fazer algumas pre condições de processamento no qual você saiba que vai retornar muitos dados.

Criado 11 de junho de 2008
Ultima resposta 12 de jun. de 2008
Respostas 1
Participantes 2