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.

Fiz testes com base nesse documento:
http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf

Já coloquei um contador no laço para a cada 25 linhas chamar o garbage…
Já coloquei a thread para dormir a cada 50 linhas linhas por 1s…

Os parâmetros que estou passando para a vm são -Xms512m -Xmx2048m, mas será que não tem como processar sem usar tanta memória?

Alguém tem mais alguma sugestão?

valeu

Ps: Estou usando BufferedReader e muito String.split

6 Respostas

G

Como está cada linha? pode postar um exemplo?
o que você faz com cada valor extraído dela?

T

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.
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
 
public class RandomAccessFileExample {
 
    public static void main(String[] args) {
        try {
            RandomAccessFile raf = new RandomAccessFile("c:/texto.txt", "rw");
            raf.seek(0);//inicio do arquivo
            while (raf.getFilePointer() < (raf.length())) {
                System.out.println(raf.readLine());
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            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

neronios

neuronio 1

classe: 1
classe_valor: 1.0

caracteristica : ordem : min : max : suporte

AAA : 0 : 10.0 : 53.0 : 0.007141703105328386 2.3763790171797073E-4 0.003512756489502124 0.0043693121471680045
0.008606294969626402 0.004891524997727429 0.006950173788540151 0.0012090254570903906 8.609404651753565E-4
0.0025066617237697493 0.006423799290613615 0.00614321187535167 0.00543041777001308 0.0044254841863469
0.004864657278098941 0.003742537648305325 0.0026141101734869815 0.006009951255237013 3.195495731674642E-4
3.8044595498533954E-4 0.004709171674383784 0.0026334870735209262 0.004349871266389636 0.002798471913166387
0.0020390139342722187 0.008225533468515697 0.0020419834800224153 0.008698921384193311 0.0018220448813664766
0.003755508072076416 0.007725247777131719 0.03136728430163917 0.053088163614860864 0.07522317993129189
0.0976526698297602 0.0913106159563244 0.07177953482950544 0.05700453799244295 0.03770165021386084
0.019281991957575895 0.005103576360215437 0.0 0.00156266892041842 0.002394158314594775 0.00302322216108
91545 0.0014030459401286094 0.00603144388103012 0.004246308346276533 0.00856945067369872 0.00649448424453
6683 0.005834642435561439 0.0032389756115189386 0.00484774008373441 0.008142206322505117 0.00707760922601
4654 0.002208884698028342 0.006835282927477433 0.006629078342840004 0.003382436263103912 0.00650222838654
7633 0.005659561727583663 0.0025251436063964414 4.473951971232089E-4 0.0029725884699494096 0.00860181668881
2318 0.0024984346665531437 0.004787048945282164 0.0019190816516985575 0.006876306675317756 0.00820863173295
1107 0.006674254242633539 0.003258868528604537 0.001339070626743269 0.004030356004014722 0.00331245139384
4754 0.006881334519635026 0.004887652826447361 0.00482764455334936 0.004215674987711147 0.00411266487794
381 0.0070511584726896176 0.008207660413542778 0.007957733519300566 0.006397406449628887 0.00360188509867
45555 0.004245141802222407 0.0066001278871421236 0.0023347699995790792 0.00313861130067219 0.00567673501969
102 0.003695477074930966 0.002705905193399927 0.0010892023347294922 0.0031163505735821496 0.00756870055855
2112 0.002430071838882126 0.005666195738699683 0.006718220518685525 0.0011047526406410117 0.00119003140787
4548 0.0036847577469418798 0.006520172573438582 0.001270702168684653 0.008083715252772511 0.00193470772791
68788 0.002381875567125424 0.0072421351980257115 0.0064668607101104215 5.827795964790312E-4 0.00454812692485
9161 0.006715845918329014 0.00687341815721929 0.007786259949507782 -0.0082809701151437

AAC : 1 : 13.0 : 40.0 : 0.006958855218510387 0.00614367010034553 0.009314339434332504 4.60193316603911E-4
0.005197196310977911 0.0017853447200149503 0.00867803440507146 0.002400192642695595 0.0012939580044138426
0.009606956306428603 0.0017822670851255068 0.006590376026338406 0.007110583843804059 0.006082297656303343
0.0015912207735015733 0.001454805614776166 9.345558181730919E-4 0.005404595936919372 0.0046168323469240324
0.007356781106833813 0.008184640609245902 0.003170658438761612 0.0017051683336707574 0.0033636756948106504
0.004590497169378614 0.006977453410620433 0.002487396070385489 5.999240440305795E-4 0.0025763729168098845
0.0032713979332904463 4.89476368486541E-4 0.007545526662671839 0.003539008817333131 0.007855168262440714
9.318971468513409E-6 0.0080425357768096 0.007764889798063559 0.0017705723973133326 5.667864054120169E-4
0.002225113412990079 0.001541835713844452 0.002498842161504945 5.034093383537279E-4 0.0010927000037782059
0.0033239134075425452 0.0064837947277416735 0.0013392315841962124 0.0029495835528186194 0.00816773024375952
0.0022822634808717726 0.006489145258182805 0.009191264190231876 0.006242231274406053 0.005653253730835342
0.005764459062047984 3.6168654533404415E-5 0.009176255899291642 0.005943802456582345 0.007575782941755526
0.008811548178412742 0.007841136063286878 0.0012438156198034261 0.0 0.0028374968812151483 0.00686956285116
4949 0.0 0.0010174336587444352 0.004124387025907746 0.0014837464351635425 0.002947547228406643 5.558252
278896377E-4 0.026090772790607213 0.047048910620501 0.07099602001648603 0.09224903776817371 0.104255
[telefone removido] 0.08131396404166967 0.06366707441881717 0.04413903217190701 0.02100589691491053 0.008339
393376823925 0.0028715440440453925 0.004368752092080291 0.004256746553113136 4.73989857995292E-4 0.008482
695530910326 0.008837811257415076 0.005502196105404009 0.007656840394257024 0.002986070292074325 1.722306
9921209184E-4 0.0019618755651379985 0.006719122498148333 0.0061691243367225585 5.165074382607144E-4 0.005492
463279852017 0.0013729598773515408 0.003515544900210176 0.0037343177983109083 0.008466441935076178 0.008484
026013766527 7.115127692438155E-4 0.008638196643181568 0.005984342226845959 0.0075224000691600755 0.008174
875079386596 0.005566328760841487 0.002301670642861907 0.006360753934787483 5.226124878879709E-4 5.823209
882195894E-4 0.0033105693155694167 0.003690256853010546 -0.007495323571209099

Uma linha inicia em AAA, outra em AAC …

fw

Dieval_Guizelini

Vou ver o funcionamento thingol.

Dieval_Guizelini
lucianotome:
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.BufferedReader in = null;
        try {
            in = new java.io.BufferedReader(new java.io.FileReader(arquivo));
            String linha;
            java.util.List<DescricaoCaracteristica> caracteristicas =
                    new java.util.ArrayList<DescricaoCaracteristica>();
            rede.setDescricaoCaracteristicas(caracteristicas);
            Classe ultimaClasse = null;
            Neuronio ultimoNeuronio = null;
            int linhasLidas = 0;
            while ((linha = in.readLine()) != null) {
                linhasLidas++;
                String aux = linha.trim();
                if (!aux.startsWith("#")) {
                    // as configurações possui o sinal de = entre a chave e o valor
                    if (aux.contains("=")) {
                        String[] confs = aux.split("=");
                        if (confs.length == 2) {
                            rede.getConfiguracao().setParametroConfiguracao(confs[0], confs[1]);
                        }
                    } else if (aux.startsWith("classe: ")) {
                        ultimaClasse = new Classe();
                        ultimaClasse.setNome(aux.substring(8));
                        ultimoNeuronio = FabricaNeuronio.novoNeuronio(rede, ultimaClasse);
                    } else if (aux.startsWith("classe_valor: ")) {
                        try {
                            ultimaClasse.setValor(Double.parseDouble(aux.substring(14).trim()));
                        } catch (Exception e) {
                        }
                    } else if (aux.contains(" : ")) {
                        // os valores da descrição e de uma caracteristica interna
                        String[] partes1 = aux.split(" : ");
                        if (partes1.length == 5) {
                            br.ufpr.sibila.fan.rede.CaracteristicaInterna ci = new br.ufpr.sibila.fan.rede.CaracteristicaInterna(
                                    rede.getConfiguracao().getTamanhoConjuntoDifuso(),
                                    rede.getConfiguracao().getRaioDifuso());
                            DescricaoCaracteristica dcar = new DescricaoCaracteristica();
                            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();
                            int limsup = fanSuport.length-1;
                            for (int ind = 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 (FileNotFoundException ex) {
            Logger.getLogger(ArquivoRede.class.getName()).log(Level.SEVERE, null, ex);
        } catch (java.io.IOException ioe) {
            Logger.getLogger(ArquivoRede.class.getName()).log(Level.SEVERE, null, ioe);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                }
            }
        }

Valeu pessoal.

Criado 12 de agosto de 2008
Ultima resposta 12 de ago. de 2008
Respostas 6
Participantes 4