Pessoal,
Tem um sistema que alimenta uma base de dados a partir de um arquivo .txt. Após alguns arquivos (uns 15 arquivos de 400KB) dá erro de estouro de memória. Já tentei configurar os parâmetros -Xms128m -Xmx512m da VM mas não adianta. Eu não sei como funciona o gerenciamento de memória, mas eu não entendo o seguinte: quando termino o processamento de um arquivo, eu abro outro e começo “do zero”, ou seja, não preciso de mais nada que está na memória. Então gostaria de saber o que está acumulando na memória para tentar alterar o código e resolver este problema.
Obrigado,
Marcos.
Estouro de memória
10 Respostas
Vc esta usando qual leitor BufferedReader, FileReader, etc… ???
depois q vc leu o arquivo vc dá um close e um flush no seu leitor ?
Você já tentou verificar quanto em memória seu programa está usando?
vê se isso lhe ajuda:
//coloque isso antes de começar a lero arquivo
Runtime runtime = Runtime.getRuntime();
System.out.println("Memória total " + runtime.totalMemory());
System.out.println("Memória antes " + runtime.freeMemory());
//aqui começa a leitura do arquivo
// após ler o arquivo coloque isso
System.out.println("Memória depois do arquivo " + runtime.freeMemory());
runtime.gc(); // chama o coletor de lixo
System.out.println("Memória livre após o coletor " + runtime.freeMemory());
Espero ter ajudado!
Qualquer cois posta o código pro pessoal dar uma olhada…
flw
Onde eu uso o flush? Pra que serve?
Resumidamente o método onde ocorre o estouro é assim:
private void contToques(String nomeArq) {
...
BufferedReader arq;
ResultSet rs = null;
try {
arq = new BufferedReader(new FileReader(nomeArq));
lin = arq.readLine();
while (lin != null) {
...
rs = con.consultar(sql);
while (rs.next()) {
...
...
}
}
...
...
rs.close();
lin = arq.readLine();
}
arq.close();
gravar();
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Obrigado.
Deise assim:
arq.flush();
arq.close();
Gilmar, não tem o método flush().
Obrigado.
Acredito que não vai ter mesmo, o método flush e utilizado quando você está gravando dados e não lendo.
O erro pode estar sendo no banco de dados, feche o ResultSet, e feche a conexão a cada finalização do método.
Fiz o teste com as mensagens de memória. Nos primeiros arquivos a quantidade de memória livre após o coletor é até maior do que antes do processamento do arquivo, depois começa a cair muito.
Fiz algumas alterações/melhorias nos métodos de conexão com o banco e aparentemente a memória parou de estourar. O sistema ficou bem mais lento, mas pelo menos não tá travando (por enquanto… hehe). Acredito que estava deixando muitas conexões abertas. Será que era isso mesmo? É normal o sistema ficar mais lento agora que estou controlando melhor as conexões?
[]'s
Use um pool de conexões com o banco; isso costuma resolver vários problemas de desempenho, já que a conexão só será aberta se não estiver disponível no pool.
Vou pesquisar sobre o assunto. Obrigado.