Lendo e persistindo arquivos de texto com mais de 20000 linhas!

Bom dia !!!

Senhores estou tentando ler e persistir um arquivo com mais de 20000 linhas em um banco de dados (postgree) estou usando, o hibernate para isso mais a lógica esta toda correta só não sei se é a melhor forma maia na hora de persistir me é mostrado um erro de OutOfMemoryError, não estou querendo aumentar o tamanho do meu HEAP pois o tamanho deste arquivo não é estável pode ser que o próximo seja bem maior, então alguem saberia como eu posso solucionar este problema pois já procurei bastante na net mais não ajudou muito…

Abaixo estou colocando o meu código onde eu estou lendo e tentanto persistir o arquivo…

@Override
    public void persistirTxt(InputStream is, GenericDao dao) throws ImportacaoException {


        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = "";
        int index = 0;

        ProcedimentoHabilitacao procedimentoHabilitacao = null;

        /**
         * Lista de todos os nrProcedimentoHobilitacao presentes no arquvo rl_prodimento_habilitacao.txt
         */
        List<String> listNrProcedimentoHabilitacao = new LinkedList<String>();
        try {

            while ((line = br.readLine()) != null) {
                procedimentoHabilitacao = new ProcedimentoHabilitacao();

                listNrProcedimentoHabilitacao.add(line.substring(0, 18));
                Integer  nrGrHab = null;
                if(!line.substring(14, 18).trim().equals("")){
                    nrGrHab = Integer.valueOf(line.substring(14, 18));
                }
                //Lista todos os ProcedimentoHabilitacao com base no nrGrupoHabilitacao
                List<ProcedimentoHabilitacao> listProcedimentoHabilitacao = (List<ProcedimentoHabilitacao>) dao.listByQueryName("procedimentoHabilitacao.listProcedimentoHabilitacaoPorNrProcedimentoENrHabilitacaoENrGrupoHabilitacao", new Object[]{line.substring(0, 10), line.substring(10, 14), nrGrHab==null?0:nrGrHab});

                //Lista os Procedimeto cadastradas p/ o nrProcedimento do arquivo
                List<Long> listProcedimento = (List<Long>) dao.listByQueryName("procedimento.listCdProcedimentoPorNr", new Object[]{line.substring(0, 10)});


                //Lista os Habilitacao cadastradas p/ o nrProcedimento do arquivo
                List<Long> listHabilitacao = (List<Long>) dao.listByQueryName("habilitacao.listCdHabilitacaoPorNr", new Object[]{line.substring(10, 14)});

                Procedimento procedimento = null;
                Habilitacao habilitacao = null;

                if (!listProcedimento.isEmpty()) {
                    procedimento = new Procedimento(listProcedimento.get(0));
                }

                if (!listHabilitacao.isEmpty()) {
                    habilitacao = new Habilitacao(listHabilitacao.get(0));
                }

                if (listProcedimentoHabilitacao.isEmpty()) {
                    procedimentoHabilitacao.setProcedimento(procedimento);
                    procedimentoHabilitacao.setHabilitacao(habilitacao);
                    procedimentoHabilitacao.setIdVigente(1);
                    procedimentoHabilitacao.setNrGrupoHabilitacao(nrGrHab);
                   dao.save(procedimentoHabilitacao);
                } else {
                    procedimentoHabilitacao = listProcedimentoHabilitacao.get(0);
                    procedimentoHabilitacao.setProcedimento(procedimento);
                    procedimentoHabilitacao.setHabilitacao(habilitacao);
                    procedimentoHabilitacao.setIdVigente(1);
                    procedimentoHabilitacao.setNrGrupoHabilitacao(nrGrHab);
                    dao.update(procedimentoHabilitacao);
                }
                                
                //Obtem o tamanho atual do heap
                long heapSize = Runtime.getRuntime().totalMemory();
                System.out.println("Tamanho atual do heap = " + heapSize + "\n");
                
                //Obtem o tmanho máximo do heap
                long heapMaxSize = Runtime.getRuntime().maxMemory();
                System.out.println("Tamanho máximo do heap = " + heapMaxSize + "\n");
                long metade  = heapMaxSize / 2;
                System.out.println("Metade do heap = " + metade+ "\n");
                
                if(heapSize >= (metade / 2)){
                    System.out.println("Sleep..." + "\n");
                    Thread.sleep(50);
                    System.gc();
                          
                }
                    
                   System.out.println("25% do heap = " + metade / 2 + "\n");
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(ProcessadorTxtProcedimentoHabilitacao.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ValidationException ex) {
            throw new ImportacaoException("Erro na importação do arquivo Procedimento Habilitação!", ex);
        } catch (IOException ex) {
            throw new ImportacaoException("Erro na importação do arquivo Procedimento Habilitação!", ex);
        }
}

Desde já agradeço…

[color=red][EDIT] inserido tags code[/color]

por favor, coloque as tags CODE no seu código para facilitar a leitura!
acredito que seja no Statement o problema, pois já fiz a leitura de arquivos com mais de 150 000 linhas tranquilamente…

Em vez de acumular as linhas lidas em um list, leia uma linha de cada vez e a processe.
Como você está fazendo:

List<String> linhas = linhas lidas do arquivo;
processarTodasAsLinhas (linhas);

Como você deve fazer:

for (String linha = br.readLine(); linha != null; linha = br.readLine()) {
     processarUmaLinha (linha);
}

Grande xxta !!!

O meu problema não esta na hora de lê o arquivo e sim na hora de persistir !!! pois me é apresentado OutOfMemoryError…Pois a forma de lê o arquivo está bem rápida…

Você está questionando a velocidade ou a quantidade de memória? Que eu saiba, ler um arquivo na memória irá carregá-la.

thingol !!!

O que está sendo acumulado nos List é um objeto de cada vez e eu preciso fazer isso pois estes objeto fazem parte da associação entre os mesmo e estão sendo buscados no banco…

Po exemplo:

em ProcedimentoHabilitacao eu preciso ir na tabela Procedimento e na tabela Habilitacao buscar os objetos com o mesmo número que esta no arquivo.txt com nome ProcedimentoHabilitação e assim salvar no banco se este objeto não existir ou atualizar se ele já existir… Então eu não sei como eu poderia implementar isso como vc mencionou.

Valeu…

thingol !!!

Com ctz mais por exemplo se eu criar um DAO Mock o arquivo é lido bem rápido e o erro não é lançado é com base nisso que eu estou afirmando que a parte de leitura do arquivo não esta me gerando este problema e sim na hora de persistir pois quando eu coloco no código o DAO para realmente persistir ai sim me é mostrado o erro…

20mil linhas eh mto para ser persistido de uma soh vez, vc teria q bolar uma outra solução… tipow… vc podeira ir grando as linhas de um arquivo text em uma tabela temporaria de outro arquivo em outra tabela temp, depois vc cria uma stored procedure que valida a regra de negocio, mantendo a integridade de sua tabela principal

vlws

Recomendo a voce dar uma olhada no comando COPY do postgres.
Para isso voce não usaria o hibernate, mas deixaria a cargo do banco de dados o processo de popular a tabela.