[RESOLVIDO]java.lang.OutOfMemoryError

Pessoal estou usando o código abaixo para pegar um txt e subir no banco,esse arquivo tem 2giga e esta dando erro de
java.lang.OutOfMemoryError como faço pra resolver esse problema!?
grato a todos

Obs: pesquisei no forum e nao achei a solução!!!


	import connectionfactory.telefonica.com.br.ConnectionFactory;
	import java.beans.Statement;
	import java.io.BufferedReader;
	import java.io.File;
	import java.io.FileNotFoundException;
	import java.io.FileReader;
	import java.io.IOException;
	import java.sql.Connection;
	import java.sql.DriverManager;
	import java.sql.PreparedStatement;
	import java.sql.SQLException;
	import java.util.ArrayList;
	import java.util.List;
	import javax.swing.JOptionPane;
	

	public class teste {
	    private static String dt_ciclo;
	    
	    //private final String dt_ciclo;
	   // private final String dt_mes_ftra;
	   // private final String dt_data;
	   // private final String dt_corte;

	    public static void main(String[] args)  throws InterruptedException, FileNotFoundException, SQLException, IOException, ClassNotFoundException {
	    
	        try{
	        System.out.println("Teste");
	        File file = new File("c:/teste/NRC_INFOS_20111031.txt"); // o path do arquivo, ex.: "C:\Importacao.txt"  
	        FileReader fileReader = new FileReader(file);  
	        BufferedReader bufferedReader = new BufferedReader(fileReader);  
	        Connection con = new ConnectionFactory().getConnection();
	        java.sql.Statement stmt =  con.createStatement();  
	  
	     List<Dados> listDados = new ArrayList<Dados>();  
	            while (bufferedReader.ready()) {  
	  
	            String linha = bufferedReader.readLine(); // lê uma linha...  
	            String[] arrayDados = linha.split("\t");  // separa os dados por seu delimitador...  
	  
	            Dados dd = new Dados();
	            dd.setProduto_comercial(arrayDados[0]);
	            dd.setNrc(arrayDados[1]);
	            dd.setSistema(arrayDados[2]);
	            dd.setSegmento(arrayDados[3]);
	            dd.setClasse(arrayDados[4]);
	            dd.setTerminal(arrayDados[5]);
	            dd.setLocalidade(arrayDados[6]);
	            dd.setCd_cliente(arrayDados[7]);
	            dd.setCd_conta(arrayDados[8]);
	            dd.setCd_pc(arrayDados[9]);
	            dd.setTp_prte(arrayDados[10]);
	            dd.setDt_ini_prqe(arrayDados[11]);
	            dd.setDt_fim_prqe(arrayDados[12]);
	            dd.setDt_ins_prqe(arrayDados[13]);
	            dd.setDt_ret_prqe(arrayDados[14]);
	            dd.setDh_prte(arrayDados[15]);
	            dd.setIn_mgro_atis_in(arrayDados[16]);
	            dd.setIn_mgro_atis_ac(arrayDados[17]);
	            dd.setIn_mgro_atis_fa(arrayDados[18]);
	            dd.setIn_mgro_atis_co(arrayDados[19]);
	            
	            
	            listDados.add(dd);
	            
	        }  
	        System.out.println("------------------------------------");  
	  
	        for (Dados dd : listDados) {  
	  
	            String sql = "insert into nrc_infos_teste(produto_comercial,nrc,sistema,segmento,classe,terminal,localidade,cd_cliente,"
	                + "cd_conta,cd_pc,tp_prte,dt_ini_prqe,dt_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 st = con.prepareStatement(sql);  
	            
	            
	            st.setString(0, dd.getProduto_comercial());
	            st.setString(1, dd.getNrc());
	            st.setString(2, dd.getSistema());
	            st.setString(3, dd.getSegmento());
	            st.setString(4,dd.getClasse());
	            st.setString(5, dd.getTerminal());
	            st.setString(6, dd.getLocalidade());
	            st.setString(7, dd.getCd_cliente());
	            st.setString(8, dd.getCd_conta());
	            st.setString(9, dd.getCd_pc());
	            st.setString(10, dd.getTp_prte());
	            st.setString(11, dd.getDt_ini_prqe());
	            st.setString(12, dd.getDt_fim_prqe());
	            st.setString(13, dd.getDt_ins_prqe());
	            st.setString(14, dd.getDt_ret_prqe());
	            st.setString(15, dd.getDh_prte());
	            st.setString(16, dd.getIn_mgro_atis_in());
	            st.setString(17, dd.getIn_mgro_atis_in());
	            st.setString(18, dd.getIn_mgro_atis_in());
	            st.setString(19, dd.getIn_mgro_atis_in());
	            
	            st.execute();
	            st.close();
	            con.close();
	        }  
	        con.commit();  
	        System.out.println(listDados);  
	        con.close();
	    }catch(SQLException e){
	        JOptionPane.showMessageDialog(null, "Erro sql" +e);
	        e.printStackTrace();
	    }
	}
	}

Aumenta a memória disponível para a JVM

Pode ser a memoria do IDE… se estiver usando o NetBeans voce terá que aumentar a memoria dele, isso caso como o marcio_gs citou não for valido.

Estou usando o eclipse como aumento a memoria da JVM?1

bom no eclipse eu não sei, apenas uso NetBeans, voce pode procurar no google que acha…
Um pergunta, você quer armazenar esses 2 GB no banco ou voce está fazendo um select??

ao invés de aumentar a memória da jvm (parâmetros de inicialização Xmx e Xms), seria muito mais inteligente você, ao invés de gravar o arquivo inteiro numa collection, ler o arquivo e já ir gravando no banco, linha a linha.

Outra sugestão, usa o addBatch do PreparedStatement. Se quiser algo mais robusto, separa uma thread para ler e outra para gravar no banco, sempre controlando que não tenha muito mais registros lidos do arquivo que os gravados no banco, e limpando a collection compartilhada entre as threads.

E a solução que eu uso, me parece que você tem um arquivo de texto em que cada linha é um registro e os campos são delimitados por tab, utiliza kettle (pentaho data integrator) para carregar no seu banco de dados que é mais prático.

bom eu utilizei o netbeans e deu o mesmo erro amigo, estou dizendo que o arquivo txt é de 2gigas
entao são muitas informações por isso o erro, como fazer para nao dar mais esse erro!?

cara nao sei como resolver mas andei dando uma olhada em dois tópicos daqui do GUJ segue abaixo

quem resolve.

alguém sabe como resolver esse problema de memoria!?

snowblacksoul: viu o que eu falei antes? Te passei diversas soluções…

Mas se quiser mesmo a do xmx e xms, no netbeans, clica com o direito no projeto, properties, run, VM Options e adiciona os parametros -Xmx3G -Xms1G (mas tenta entender o que ambos os parâmetros fazem, não é difícil de encontrar). No eclipse, se não me engano, era em Run, Run Configurations, mas não lembro (faz tempo que não uso o eclipse)

Oi snowblacksoul,

O ideal ai, ao meu ver, é ter uma threadpool cujo objetivo é ir fazendo esse insert no banco.
Estou dizendo isso porque, a princípio, ler um arquivo (localmente) é mais rápido do que gravar uma informação em um banco que não está na mesma máquina.

Você sabe o que é uma threadpool? Sabe como implementá-la em java?

Existem alguns tópicos no google a respeito, talvez seja uma boa saída.

Seu problema é memória…(Nossa que sacada…kk)

Use o profile e verifique em que momento voce esta criando objetos e não esta liberando eles. Não é pq seu arquiivo tem 2gb que sua jvm tem q ter 2gb. A solução é vc saber trabalhar com os objetos q vc cria e eliminar as referencia para o garbage poder coletar.
O profile vai te dizer onde esta o gargalo e vc trabalha seu codigo para corrigir o problema. vc disse que trabalha com o netbenas, e o profile dele é exelente(na minha opnião).

Agora se vc ao sabe o q é profile, procura no google.

evefuji achei interessante a primeira e a segunda dica que vc mostrou, mas nao sei como fazer poderia dar um exemplo!!

evefuji valeu pela dica cara, ao invés de colocar tudo na memoria, estou gravando linha a linha no banco, muito bom valeu mesmo!!!

solução


	import connectionfactory.telefonica.com.br.ConnectionFactory;
	import java.beans.Statement;
	import java.io.BufferedReader;
	import java.io.File;
	import java.io.FileNotFoundException;
	import java.io.FileReader;
	import java.io.IOException;
	import java.sql.Connection;
	import java.sql.DriverManager;
	import java.sql.PreparedStatement;
	import java.sql.SQLException;
	import java.util.ArrayList;
	import java.util.List;
	import javax.swing.JOptionPane;
	

	public class teste {
	    private static String dt_ciclo;
	    
	    //private final String dt_ciclo;
	   // private final String dt_mes_ftra;
	   // private final String dt_data;
	   // private final String dt_corte;

	    public static void main(String[] args)  throws InterruptedException, FileNotFoundException, SQLException, IOException, ClassNotFoundException {
	    
	        try{
	        System.out.println("Teste");
	        File file = new File("c:/teste/NRC_INFOS_20111031.txt"); // o path do arquivo, ex.: "C:\Importacao.txt"  
	        FileReader fileReader = new FileReader(file);  
	        BufferedReader bufferedReader = new BufferedReader(fileReader);  
	        Connection con = new ConnectionFactory().getConnection();
	        java.sql.Statement stmt =  con.createStatement();  
	  
	     List<Dados> listDados = new ArrayList<Dados>();  
	            while (bufferedReader.ready()) {  
	  
	            String linha = bufferedReader.readLine(); // lê uma linha...  
	            String[] arrayDados = linha.split("\t");  // separa os dados por seu delimitador...  
	  
	            Dados dd = new Dados();
	            dd.setProduto_comercial(arrayDados[0]);
	            dd.setNrc(arrayDados[1]);
	            dd.setSistema(arrayDados[2]);
	            dd.setSegmento(arrayDados[3]);
	            dd.setClasse(arrayDados[4]);
	            dd.setTerminal(arrayDados[5]);
	            dd.setLocalidade(arrayDados[6]);
	            dd.setCd_cliente(arrayDados[7]);
	            dd.setCd_conta(arrayDados[8]);
	            dd.setCd_pc(arrayDados[9]);
	            dd.setTp_prte(arrayDados[10]);
	            dd.setDt_ini_prqe(arrayDados[11]);
	            dd.setDt_fim_prqe(arrayDados[12]);
	            dd.setDt_ins_prqe(arrayDados[13]);
	            dd.setDt_ret_prqe(arrayDados[14]);
	            dd.setDh_prte(arrayDados[15]);
	            dd.setIn_mgro_atis_in(arrayDados[16]);
	            dd.setIn_mgro_atis_ac(arrayDados[17]);
	            dd.setIn_mgro_atis_fa(arrayDados[18]);
	            dd.setIn_mgro_atis_co(arrayDados[19]);
	            
	            
	            listDados.add(dd);
                    for (Dados ddd : listDados) {  
	  
	            String sql = "insert into nrc_infos_teste(produto_comercial,nrc,sistema,segmento,classe,terminal,localidade,cd_cliente,"
	                + "cd_conta,cd_pc,tp_prte,dt_ini_prqe,dt_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 st = con.prepareStatement(sql);  
	            
	            
	            st.setString(0, ddd.getProduto_comercial());
	            st.setString(1, ddd.getNrc());
	            st.setString(2, ddd.getSistema());
	            st.setString(3, ddd.getSegmento());
	            st.setString(4,ddd.getClasse());
	            st.setString(5, ddd.getTerminal());
	            st.setString(6, ddd.getLocalidade());
	            st.setString(7, ddd.getCd_cliente());
	            st.setString(8, ddd.getCd_conta());
	            st.setString(9, ddd.getCd_pc());
	            st.setString(10, ddd.getTp_prte());
	            st.setString(11, ddd.getDt_ini_prqe());
	            st.setString(12, ddd.getDt_fim_prqe());
	            st.setString(13, ddd.getDt_ins_prqe());
	            st.setString(14, ddd.getDt_ret_prqe());
	            st.setString(15, ddd.getDh_prte());
	            st.setString(16, ddd.getIn_mgro_atis_in());
	            st.setString(17, ddd.getIn_mgro_atis_in());
	            st.setString(18, ddd.getIn_mgro_atis_in());
	            st.setString(19, ddd.getIn_mgro_atis_in());
	            
	            st.execute();
	            st.close();
	            con.close();
	       
	            
	        }  
	        
	  
	       }  
	        con.commit();  
	        System.out.println(listDados);  
	        con.close();
	    }catch(SQLException e){
	        JOptionPane.showMessageDialog(null, "Erro sql" +e);
	        e.printStackTrace();
	    }
	}
	}

Oi!

Eu acho que tu vai duplicar dados ai parceiro. Percebeu que tu adiciona um objeto a lista e em seguida realiza uma iteração sobre ela para persistir os dados?
Ai tu persiste o primeiro, ok…depois adiciona o segunda a mesma lista e percorre ela, persiste novamente o primeiro item e o segunda e assim por diante.

putz verdade nel, o que posso fazer nesse caso!?

Ué, percebeu que é uma lista “inutíl”? Ela armaneza dentro de outro laço de repetição para ler o arquivo.
Se tu já tem o objeto criado com informações do arquivo, simplesmente salve ele em banco e ponto final.

Simplesmente não tem motivos para existir essa lista.

putz nel!!
Ainda não compreendi muito bem, estou engatinhando em java ainda cara!!
pode me dar um auxilio?!

[quote=snowblacksoul]putz nel!!
Ainda não compreendi muito bem, estou engatinhando em java ainda cara!!
pode me dar um auxilio?![/quote]

Veja esse trecho da solução postada por você:

[code]List<Dados> listDados = new ArrayList<Dados>();
while (bufferedReader.ready()) {

        String linha = bufferedReader.readLine(); // lê uma linha...    
        String[] arrayDados = linha.split("\t");  // separa os dados por seu delimitador...    

        Dados dd = new Dados();  
        dd.setProduto_comercial(arrayDados[0]);  
        dd.setNrc(arrayDados[1]);  
        dd.setSistema(arrayDados[2]);  
        dd.setSegmento(arrayDados[3]);  
        dd.setClasse(arrayDados[4]);  
        dd.setTerminal(arrayDados[5]);  
        dd.setLocalidade(arrayDados[6]);  
        dd.setCd_cliente(arrayDados[7]);  
        dd.setCd_conta(arrayDados[8]);  
        dd.setCd_pc(arrayDados[9]);  
        dd.setTp_prte(arrayDados[10]);  
        dd.setDt_ini_prqe(arrayDados[11]);  
        dd.setDt_fim_prqe(arrayDados[12]);  
        dd.setDt_ins_prqe(arrayDados[13]);  
        dd.setDt_ret_prqe(arrayDados[14]);  
        dd.setDh_prte(arrayDados[15]);  
        dd.setIn_mgro_atis_in(arrayDados[16]);  
        dd.setIn_mgro_atis_ac(arrayDados[17]);  
        dd.setIn_mgro_atis_fa(arrayDados[18]);  
        dd.setIn_mgro_atis_co(arrayDados[19]);  
          
          
        listDados.add(dd);  
               for (Dados ddd : listDados) {    

        String sql = "insert into nrc_infos_teste(produto_comercial,nrc,sistema,segmento,classe,terminal,localidade,cd_cliente,"  
            + "cd_conta,cd_pc,tp_prte,dt_ini_prqe,dt_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 st = con.prepareStatement(sql);    
          
          
        st.setString(0, ddd.getProduto_comercial());  
        st.setString(1, ddd.getNrc());  
        st.setString(2, ddd.getSistema());  
        st.setString(3, ddd.getSegmento());  
        st.setString(4,ddd.getClasse());  
        st.setString(5, ddd.getTerminal());  
        st.setString(6, ddd.getLocalidade());  
        st.setString(7, ddd.getCd_cliente());  
        st.setString(8, ddd.getCd_conta());  
        st.setString(9, ddd.getCd_pc());  
        st.setString(10, ddd.getTp_prte());  
        st.setString(11, ddd.getDt_ini_prqe());  
        st.setString(12, ddd.getDt_fim_prqe());  
        st.setString(13, ddd.getDt_ins_prqe());  
        st.setString(14, ddd.getDt_ret_prqe());  
        st.setString(15, ddd.getDh_prte());  
        st.setString(16, ddd.getIn_mgro_atis_in());  
        st.setString(17, ddd.getIn_mgro_atis_in());  
        st.setString(18, ddd.getIn_mgro_atis_in());  
        st.setString(19, ddd.getIn_mgro_atis_in());  
          
        st.execute();  
        st.close();  
        con.close();  
     
          
    } [/code]

Aqui tem a falha na qual citei, de duplicar dados.
Você tem dois laços de repetição colega, um para leitura do arquivo ( while (bufferedReader.ready()) ) outro que persistir os dados ( for (Dados ddd : listDados) ).
Não existe a menor possibilidade de carregar uma lista com informações que já podem ser persistidas diretamente, como é o seu caso. Você, inclusive, não precisa nem criar um novo objeto, pode simplesmente pegar o valor do TXT e salvar, mas vou lhe dar da forma como fez, usando objeto:

[code]
String sql = “insert into nrc_infos_teste(produto_comercial,nrc,sistema,segmento,classe,terminal,localidade,cd_cliente,”
+ “cd_conta,cd_pc,tp_prte,dt_ini_prqe,dt_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(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)”;

        while (bufferedReader.ready()) {    

        String linha = bufferedReader.readLine(); // lê uma linha...    
        String[] arrayDados = linha.split("\t");  // separa os dados por seu delimitador...    

        Dados dd = new Dados();  
        dd.setProduto_comercial(arrayDados[0]);  
        dd.setNrc(arrayDados[1]);  
        dd.setSistema(arrayDados[2]);  
        dd.setSegmento(arrayDados[3]);  
        dd.setClasse(arrayDados[4]);  
        dd.setTerminal(arrayDados[5]);  
        dd.setLocalidade(arrayDados[6]);  
        dd.setCd_cliente(arrayDados[7]);  
        dd.setCd_conta(arrayDados[8]);  
        dd.setCd_pc(arrayDados[9]);  
        dd.setTp_prte(arrayDados[10]);  
        dd.setDt_ini_prqe(arrayDados[11]);  
        dd.setDt_fim_prqe(arrayDados[12]);  
        dd.setDt_ins_prqe(arrayDados[13]);  
        dd.setDt_ret_prqe(arrayDados[14]);  
        dd.setDh_prte(arrayDados[15]);  
        dd.setIn_mgro_atis_in(arrayDados[16]);  
        dd.setIn_mgro_atis_ac(arrayDados[17]);  
        dd.setIn_mgro_atis_fa(arrayDados[18]);  
        dd.setIn_mgro_atis_co(arrayDados[19]);  
          
        PreparedStatement st = con.prepareStatement(sql);   
        st.setString(0, ddd.getProduto_comercial());  
        st.setString(1, ddd.getNrc());  
        st.setString(2, ddd.getSistema());  
        st.setString(3, ddd.getSegmento());  
        st.setString(4,ddd.getClasse());  
        st.setString(5, ddd.getTerminal());  
        st.setString(6, ddd.getLocalidade());  
        st.setString(7, ddd.getCd_cliente());  
        st.setString(8, ddd.getCd_conta());  
        st.setString(9, ddd.getCd_pc());  
        st.setString(10, ddd.getTp_prte());  
        st.setString(11, ddd.getDt_ini_prqe());  
        st.setString(12, ddd.getDt_fim_prqe());  
        st.setString(13, ddd.getDt_ins_prqe());  
        st.setString(14, ddd.getDt_ret_prqe());  
        st.setString(15, ddd.getDh_prte());  
        st.setString(16, ddd.getIn_mgro_atis_in());  
        st.setString(17, ddd.getIn_mgro_atis_in());  
        st.setString(18, ddd.getIn_mgro_atis_in());  
        st.setString(19, ddd.getIn_mgro_atis_in());  
          
        st.execute();  
        st.close();  
        con.close();  
     
          
    } [/code]

Pronto, agora você lê o arquivo, popula as informações em um objeto e depois salva esses valores no banco. Você pode inclusive fazer direto, assim por exemplo:

st.setString(0, arrayDados[0]);

Assim, tu não declara um objeto desnecessário, já que tu já tem a informação desejada em outro objeto, que é o array, certo? :slight_smile:
Também perceba que eu removi sua String ‘sql’ de dentro do laço de repetição, afinal, ela é ‘fixa’ e nunca é alterada, portanto, não tem necessidade de sempre criar uma nova String para cada iteração da sua lista.

Outro detalhe muito importante, depois de tudo ok, procure usar bloco finally para fechar os ResultSet, PreparedStatement e Connection.