Problema chato: OutOfMemory no processamento de arquivo texto
6 respostas
Dieval_Guizelini
Senhores,
estou processando um arquivo texto que possui 798.974.950 bytes, durante a fase de leitura e análise desse arquivo possuo várias linhas do tipo parametro = valor.
E muitas linhas com vários valores delimitados por \t.
Quando o arquivo está processado, os objetos com os respetivos valores (a maioria são double) ocupam no máximo 300mb.
O problema está durante o processamento mesmo do arquivo texto, já utilizei algumas configurações para aumentar o heap e já fiz testes com outros gc e não consegui resolver o problema do out of memory.
Como está cada linha? pode postar um exemplo?
o que você faz com cada valor extraído dela?
T
thingol
Pergunta boba - há um número relativamente pequeno de nomes de parâmetros e os valores são em sua maioria numéricos? Experimente pegar os nomes dos parâmetros, e usar String.intern.
lucianotome
Dieval, nao sei se isso pode te ajudar, mas tenta usar RandomAccessFile, vc pode acessar linha por linha e descartar as ja lidas.
importjava.io.FileNotFoundException;importjava.io.IOException;importjava.io.RandomAccessFile;publicclassRandomAccessFileExample{publicstaticvoidmain(String[]args){try{RandomAccessFileraf=newRandomAccessFile("c:/texto.txt","rw");raf.seek(0);//inicio do arquivowhile(raf.getFilePointer()<(raf.length())){System.out.println(raf.readLine());}}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}}}
Dieval_Guizelini
gustavo_apsilva:
Como está cada linha? pode postar um exemplo?
o que você faz com cada valor extraído dela?
Gustavo, segue um pequeno exemplo, ele possui o cabeçalho e duas linhas da primeira classe, são ao todo 5164 classes, cada classe possui 64 caracteristicas (cada caracteristica dessa é uma linha).
# configuracao utilizada na rede
raioDifuso = 6
tamanhoConjuntoDifuso = 100
peso = 0
normalizador = max
inicializadorNeuronios = br.ufpr.sibila.fan.rede.neuronio.InicializadorRandomico
Dieval, nao sei se isso pode te ajudar, mas tenta usar RandomAccessFile, vc pode acessar linha por linha e descartar as ja lidas.
}
Oi Luciano,
valeu pela dica, mas acho que o problema não está na leitura.
Se eu fizer um programa para apenas ler e despejar no console ele não consome tanta memória...
Segue a parte do código para vocês darem uma olhada:
java.io.BufferedReaderin=null;try{in=newjava.io.BufferedReader(newjava.io.FileReader(arquivo));Stringlinha;java.util.List<DescricaoCaracteristica>caracteristicas=newjava.util.ArrayList<DescricaoCaracteristica>();rede.setDescricaoCaracteristicas(caracteristicas);ClasseultimaClasse=null;NeuronioultimoNeuronio=null;intlinhasLidas=0;while((linha=in.readLine())!=null){linhasLidas++;Stringaux=linha.trim();if(!aux.startsWith("#")){// as configurações possui o sinal de = entre a chave e o valorif(aux.contains("=")){String[]confs=aux.split("=");if(confs.length==2){rede.getConfiguracao().setParametroConfiguracao(confs[0],confs[1]);}}elseif(aux.startsWith("classe: ")){ultimaClasse=newClasse();ultimaClasse.setNome(aux.substring(8));ultimoNeuronio=FabricaNeuronio.novoNeuronio(rede,ultimaClasse);}elseif(aux.startsWith("classe_valor: ")){try{ultimaClasse.setValor(Double.parseDouble(aux.substring(14).trim()));}catch(Exceptione){}}elseif(aux.contains(" : ")){// os valores da descrição e de uma caracteristica internaString[]partes1=aux.split(" : ");if(partes1.length==5){br.ufpr.sibila.fan.rede.CaracteristicaInternaci=newbr.ufpr.sibila.fan.rede.CaracteristicaInterna(rede.getConfiguracao().getTamanhoConjuntoDifuso(),rede.getConfiguracao().getRaioDifuso());DescricaoCaracteristicadcar=newDescricaoCaracteristica();dcar.setNome(partes1[0]);dcar.setOrdem(Integer.parseInt(partes1[1]));dcar.setValorMinimo(Double.parseDouble(partes1[2]));dcar.setValorMaximo(Double.parseDouble(partes1[3]));caracteristicas.add(dcar);String[]fanSuport=partes1[4].split("\t");double[]mat=ci.getMatriz();intlimsup=fanSuport.length-1;for(intind=0;ind<limsup;ind++){mat[ind]=Double.parseDouble(fanSuport[ind]);}ci.setTotalPenalizacao(Double.parseDouble(fanSuport[limsup]));}else{System.out.println("Contexto inesperado no arquivo de configuração: linha "+linhasLidas);}}}if(linhasLidas%25==0){System.out.println(linhasLidas);System.gc();}}}catch(FileNotFoundExceptionex){Logger.getLogger(ArquivoRede.class.getName()).log(Level.SEVERE,null,ex);}catch(java.io.IOExceptionioe){Logger.getLogger(ArquivoRede.class.getName()).log(Level.SEVERE,null,ioe);}finally{if(in!=null){try{in.close();}catch(Exceptione){}}}