Erro ao ler um arquivo txt ? =Exception in thread "main" java.lang.OutOfMemoryError: Java heap

Bom dia a todos, sei que esse tópico tem no GUJ, mas não específico com o netbeans e o tamanho do arquivo que estou pegando.
Seguinte, preciso subir no banco esse arquivo txt que vai de 150MB a 3Gigas e está dando erro de "java.lang.OutOfMemoryError: Java heap " vou colocar o código para que todos tenham ideia do que estou fazendo e preciso!
Tem alguma solução para pegar arquivos GRANDES, como fazer?!
gratos a todos que puderem colaborar

Aqui o código

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */



import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author E449045
 */
public class ImportNrcInfos {

    public static void main(String[] args) throws FileNotFoundException, ClassNotFoundException, SQLException, IOException {   
  
       File file = new File("c:/teste/NRC_INFOS_20110801.txt"); // o path do arquivo, ex.: "C:\Importacao.txt"   
       FileReader fileReader = new FileReader(file);   
       BufferedReader bufferedReader = new BufferedReader(fileReader);  
      //  File file = new File(new BufferedReader(new FileReader("c:/teste/NRC_INFOS_20110801.txt")));
                                     
            //sqljdbc/sqljdbc4/jtds-1.2
              Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
                Connection connection = DriverManager.getConnection("jdbc:sqlserver://SRV_RG:1433;databaseName=BASES","pa","****");
                System.out.println("conectado");
        
            Statement stmt = (Statement) connection.createStatement();   
  
     		List<Infos> listLivros = new ArrayList<Infos>();   
             while (bufferedReader.ready()) {   
  
            String linha = bufferedReader.readLine(); // lê uma linha...   
            String[] arrayDados = linha.split("\t");  // separa os dados por seu delimitador...   

            Infos livro = new Infos(); 
           livro.setPRODUTO_COMERCIAL(arrayDados[0]);
           livro.setNRC(arrayDados[1]);
           livro.setSISTEMA(arrayDados[2]);
           livro.setSEGMENTO(arrayDados[3]);
           livro.setCLASSE(arrayDados[4]);
           livro.setTERMINAL(arrayDados[5]);
           livro.setLOCALIDADE(arrayDados[6]);
           livro.setCD_CLIENTE(arrayDados[7]);
           livro.setCD_CONTA(arrayDados[8]);
           livro.setCD_PC(arrayDados[9]);
           livro.setTP_PRTE(arrayDados[10]);
           livro.setDT_INI_PRQE(arrayDados[11]);
           livro.setDT_FIM_PRQE(arrayDados[12]);
           livro.setDT_INS_PRQE(arrayDados[13]);
           livro.setDT_RET_PRQE(arrayDados[14]);
           livro.setDH_PRTE(arrayDados[15]);
           livro.setIN_MGRO_ATIS_IN(arrayDados[16]);   
           livro.setIN_MGRO_ATIS_AC(arrayDados[17]);   
           livro.setIN_MGRO_ATIS_FA(arrayDados[18]);   
           livro.setIN_MGRO_ATIS_CO(arrayDados[19]);   
                                 
        listLivros.add(livro);   
        }   
		System.out.println("------------------------------------");   
  
        for (Infos livro : listLivros) {   
  
            String sentenca = "insert into dbo.NRC_INFOS_201108(PRODUTO_COMERCIAL,NRC,SISTEMA,SEGMENTO,CLASSE,TERMINAL,LOCALIDADE,"
                    + "CD_CLIENTE,CD_CONTA,CD_PC,TP_PRTE,DT_INI_PRQE,DT_FIM_PRQE,DT_INS_PRQE,"
                    + "DT_RET_PRQE,DH_PRTE,IN_MGRO_ATIS_IN,IN_MGRO_ATIS_AC,"
                    + "IN_MGRO_ATIS_FA,IN_MGRO_ATIS_CO) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";   
            PreparedStatement statementInsert = connection.prepareStatement(sentenca); 
            
            statementInsert.setString(1, livro.getPRODUTO_COMERCIAL());   
            statementInsert.setString(2, livro.getNRC()); 
            statementInsert.setString(3, livro.getSISTEMA()); 
            statementInsert.setString(4, livro.getSEGMENTO()); 
            statementInsert.setString(5, livro.getCLASSE()); 
            statementInsert.setString(6, livro.getTERMINAL()); 
            statementInsert.setString(7, livro.getLOCALIDADE()); 
            statementInsert.setString(8, livro.getCD_CLIENTE()); 
            statementInsert.setString(9, livro.getCD_CONTA()); 
            statementInsert.setString(10, livro.getCD_PC()); 
            statementInsert.setString(11, livro.getTP_PRTE()); 
            statementInsert.setString(12, livro.getDT_INI_PRQE()); 
            statementInsert.setString(13, livro.getDT_FIM_PRQE()); 
            statementInsert.setString(14, livro.getDT_INS_PRQE()); 
            statementInsert.setString(15, livro.getDT_RET_PRQE()); 
            statementInsert.setString(16, livro.getDH_PRTE()); 
            statementInsert.setString(17, livro.getIN_MGRO_ATIS_IN());          
            statementInsert.setString(18, livro.getIN_MGRO_ATIS_AC());   
            statementInsert.setString(19, livro.getIN_MGRO_ATIS_FA());   
            statementInsert.setString(20, livro.getIN_MGRO_ATIS_CO());   
              
            statementInsert.execute();   
           // statementInsert.executeUpdate();   
            //stmt.executeUpdate(sentenca);   
        }   
        connection.commit();   
        System.out.println(listLivros);   
  
    }   
}

O Erro!

Mas oque voce precisa fazer com este arquivo? Exibir? Manipular?

Cara, não manjo muito, mas se voce esta tentando fazer isso com arquivos de 150mb pra mais e esta dando erro de memória, tenta executar com um arquivo menor, ou voce pode tentar importar o projeto para o Eclipse e tentar pelo menos ‘abrir’ o arquivo na memoria…

Quem sabe funciona,

Boa sorte :smiley:

Oi!

Tu consegue imaginar jogar 3 GB em um Buffer de memória?
Terás de pensar muito bem na sua manipulação do arquivo, principalmente porque ao que vi existem dois laços de repetição:

1 - Leitura e armazenamento em memório das informações
2 - Inserir no banco

Não acredito que com as configurações default da JVM tu vá conseguir fazer isso meu caro, acredito que terás de aumentar consideravelmente o HEAP da sua JVM e quebrar em pedaços esse arquivo, assim como é feito em um download de arquivo, por exemplo.

Eu já imaginei isso!
Sem usar as configurações da JVM, existe um outro meio de fazer isso
sem utilizar a memoria!?

os arquivos aqui são relativamente grandes, e não queria mais usar a dts do ruinwindows!!

Olha assim se cara acho que não, voce teria que associar um arquivo de swap no HD para so esse processo, o que, SE der certo vai demorar pra fazer todo o processamento…

Em vez de acumular todos os livros para inserção posterior, por que não inserir cada livro assim que tiver acabado de lê-lo?

como assim roger?

Assim:

String linha = bufferedReader.readLine();
while (linha != null) {
  Infos livro = new Infos();
  /* ... PENDENTE: Preencher [livro] a partir de [linha] ... */
  /* ... PENDENTE: Inserir [livro] no Banco de Dados ... */
  linha = bufferedReader.readLine();
}

Você não precisa acumular os livros no ArrayList para gravá-los no BD posteriormente, basta gravar o livro no BD assim que tiver acabado de lê-lo do arquivo de texto.

Não sou o Roger, mas entendi o que ele quis dizer…

Ao invés de você fazer assim…

while (bufferedReader.ready()) {   
... 
listLivros.add(livro);    //Estou guardando TUDO em memória
}   

Viu como você está lendo o txt todinho e “guardando em memória” para depois…

for (Infos livro : listLivros) {   // Estou lendo da memória
...  
}   

… ler da memória e gravar no banco…

A minha sugestão é a seguinte:

1 - Leia a linha;
2 - faça os tratamentos necessários;
3 - grave no banco.

e assim sucessivamente até acabar o arquivo.

Espero ter ajudado…

Pessoal não tem memoria que aguente !!!

eu tenho um texto com mais de 120 mil linhas.

o certo ler uma linha e salva no banco …
ler a proxima e salva no banco a te o fim.

como vc ja tem exemplos ai vai mais um … esse forum é D + :lol: :smiley: fala ai … pessoal

o codigo abaixo é para arquivo pequeno !!!



import java.io.*;
import javax.swing.*;

public class lertxttod {

	public String nomArq;

	public lertxttod(String arqv) {
		{
		    nomArq = arqv;
		}			
	}



	public String lerArquivotexto()  {
		String result = "";
	try {

		BufferedReader br = new BufferedReader(new FileReader(nomArq));

		String dados=" ";
		while ((dados = br.readLine()) != null)   // lendo texto
		{ 
//			result = result + dados + "\n";
AQUI SALVA NO BANCO
		} 

		return result;
	}

			catch (IOException ioe) {
				JOptionPane.showMessageDialog(null,
				"Erro de leitura no arquivo " + nomArq + "'",
				"Mensagem",	JOptionPane.PLAIN_MESSAGE );
			result = ""; 
			}

	return result;
	}

}

espero ter contribuido tambem junto com a pessoal acima …

entendi Danilo!!!

valeu Lindberg
vou testar aqui e respondo depois do almoço galera!!
ta fogo esse post rsrsrs

Oi!

Um artigo interessante para uso: Tuning Java I/O Performance.
Leia, extrai a informação e persista no banco.

Mas pera ae pessoal, não seria mais fácil ao invés de criar um txt para subir no banco,pegar as informações direto no banco de dados e importar em outro banco!!
Isso é possível!?

[quote=snowblacksoul]Mas pera ae pessoal, não seria mais fácil ao invés de criar um txt para subir no banco,pegar as informações direto no banco de dados e importar em outro banco!!
Isso é possível!?[/quote]

Mas calma digo eu…tu quer fazer um Dump, é isso?
Quer migrar informações de um banco de dados para outro e atualmente está usando um arquivo TXT para intermediar isso?

Isso mesmo Nel, estou criando um txt de um banco e importando as informações em outro banco!
Pensando, não seria muito mais fácil fazer daquela forma que falei, ao invés de criar o txt!?

[quote=snowblacksoul]Isso mesmo Nel, estou criando um txt de um banco e importando as informações em outro banco!
Pensando, não seria muito mais fácil fazer daquela forma que falei, ao invés de criar o txt!?[/quote]

Na minha opinião, sem dúvidas.
Pode ir na base de dados e carregar o ResultSet de 100 em 100 registros e ir gravando aos poucos no outro banco.
Muio provávél que tu não tenha mais o problema de Heap.

Não não sei implementar dessa forma, como ficaria isso?! esse resultset?!