OutOfMemoryError, AJUDA!

31 respostas
S
public static void getTabela(){
        try{

        File f = new File("Local");

        if ( f.exists() ){

                FileReader fr = new FileReader( f );
                BufferedReader leitor = new BufferedReader(fr);
                String linha;
                        do{
                                linha = leitor.readLine();
                                quebrarLinha(linha);	
                    }while(linha!=null);
                        leitor.close();
                        conn.close();
                }	
        }
        catch(IOException ex){
            System.out.println("Problema ao iniciar o arquivo");
        }
        catch(Exception e){  
              e.printStackTrace();  
        }
    }
    public static void quebrarLinha(String linha){
        if(linha!=null){
            String[] vetor = linha.split("\t");
            popularBanco(vetor);
        }
    }
    public static void popularBanco(String[] vetor){
        try{
            String importar = "INSERT INTO dar_tr_stroke VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
            PreparedStatement ps = conn.prepareStatement(importar);
            for(int i=0; i<vetor.length; i++){
                ps.setString(i+1, vetor[i]);
            }
            ps.executeUpdate();
        }
        catch(SQLException ex){
            ex.printStackTrace();
            System.out.println("Impossivel de se inserir");
        }
        
    }
   public static Connection getConnection(){  
      try{  
         Class.forName("com.mysql.jdbc.Driver");  
         conn = DriverManager.getConnection(dbUrl,user,password);  

       }catch(Exception e){  
          e.printStackTrace();  
          System.out.println("Não foi possível se conectar");
    }  
       return conn;  
    }    
   
    private static String dbUrl="jdbc:mysql://localhost:3306/meuServer";  
    private static String user="root";  
    private static String password="1234";  
    private static Connection conn;

Galera, tenho que inserir em um banco com tabela de 25 colunas, um arquivo de 110 mega ta estorando a memória da minha mv;
Já to abrindo o netbeans com 400mb de base usando o tal comando ““C:\Arquivos de programas\NetBeans 6.0.1\bin\netbeans.exe” -vm C:\Arquivos de programas\Java\jdk1.6.0_04\jre\bin\javaw.exe -vmargs -Xms400m -Xmx500m”

Gostaria de saber se nao tem algum gargalo no meu código, ou se é normal isso e devo colocar logo 1gb pra abrir.
Por favor, nao to sabendo realmente o que fazer hehe.

31 Respostas

J
sephct:
public static void getTabela(){
        try{

        File f = new File("Local");

        if ( f.exists() ){

                FileReader fr = new FileReader( f );
                BufferedReader leitor = new BufferedReader(fr);
                String linha;
                        do{
                                linha = leitor.readLine();
                                quebrarLinha(linha);	
                    }while(linha!=null);
                        leitor.close();
                        conn.close();
                }	
        }
        catch(IOException ex){
            System.out.println("Problema ao iniciar o arquivo");
        }
        catch(Exception e){  
              e.printStackTrace();  
        }
    }
    public static void quebrarLinha(String linha){
        if(linha!=null){
            String[] vetor = linha.split("\t");
            popularBanco(vetor);
        }
    }
    public static void popularBanco(String[] vetor){
        try{
            String importar = "INSERT INTO dar_tr_stroke VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
            PreparedStatement ps = conn.prepareStatement(importar);
            for(int i=0; i<vetor.length; i++){
                ps.setString(i+1, vetor[i]);
            }
            ps.executeUpdate();
        }
        catch(SQLException ex){
            ex.printStackTrace();
            System.out.println("Impossivel de se inserir");
        }
        
    }
   public static Connection getConnection(){  
      try{  
         Class.forName("com.mysql.jdbc.Driver");  
         conn = DriverManager.getConnection(dbUrl,user,password);  

       }catch(Exception e){  
          e.printStackTrace();  
          System.out.println("Não foi possível se conectar");
    }  
       return conn;  
    }    
   
    private static String dbUrl="jdbc:mysql://localhost:3306/meuServer";  
    private static String user="root";  
    private static String password="1234";  
    private static Connection conn;

Galera, tenho que inserir em um banco com tabela de 25 colunas, um arquivo de 110 mega ta estorando a memória da minha mv;
Já to abrindo o netbeans com 400mb de base usando o tal comando ""C:\Arquivos de programas\NetBeans 6.0.1\bin\netbeans.exe" -vm C:\Arquivos de programas\Java\jdk1.6.0_04\jre\bin\javaw.exe -vmargs -Xms400m -Xmx500m"

Gostaria de saber se nao tem algum gargalo no meu código, ou se é normal isso e devo colocar logo 1gb pra abrir.
Por favor, nao to sabendo realmente o que fazer hehe.

Brother... boa noite !

Uma das best pratices é fazer o fechamento dos objetos (Connection, ResultSet, Statements), pelo que vi em seu aplicativo, não há este fechamento... outro detalhe, sempre coloque os métodos de fechamento no escopo FINALLY de seu try/catch, uma vez que ocorra qualquer exceçao anteriormente você ficará com tais objetos aberto... em um sistema online que tenha pool de conexões e etc isso seria problema crítico.

Por exemplo, ficaria assim:
try{
PreparedStatement ps = conn.prepareStatement(importar);
for(int i=0; i ps.setString(i+1, vetor[i]);
}
ps.executeUpdate();
} catch(SQLException ex){
ex.printStackTrace();
System.out.println("Impossivel de se inserir");
} finally {
if ( ps != null ) //garantir que nao terá problemas... caso sua conexao esteja c/problemas
ps.close();
}

Outro ponto... a mesma coisa.. coloque o close no Finally... fazendo as validacoes evitando null pointer exception...

if ( f.exists() ){

FileReader fr = new FileReader( f );
BufferedReader leitor = new BufferedReader(fr);
String linha;
do{
linha = leitor.readLine();
quebrarLinha(linha);
}while(linha!=null);
}
}

.... finally {
if ( leitor != null ) leitor.close();
if ( conn != null ) conn.close();
}

Com isto você já estará liberando alguma memória.... outra coisa é dar uma olhada em outros objetos de leitura de arquivos....

Abraços

S

Blz, entendi. uma coisa que um amigo meu com mais exp me disse, foi para criar um vetor de comando para o mysql por exemplo, passando diversos “INSERT INTO…” de uma vez e fazer ele rodar de uma vez só, por exemplo 1k de linha de uma vez, já que meu programa da pau na hora que ele popula 10k de linhas no banco.
Amanha no trabalho irei testar isso.

E juliano, que outros tipo de leitores de arquivos? Eu naoconheco, pensei que só tinha o FileReader().

S

Ainda precisando de alguma dica pra conseguir melhorar isso, se alguém se dispor. Vlw galera.

ivo_costa

Tentou debugar pra ver onde é que ocorre o erro?

S

Consegui fazer rodar, agora só colocando um p.close(); em uma linha eu consegui liberar memória.
Vlw Juliano.

Porém o desempenho não está muito bom, o programa já está rodando faz uns 15 minutos, populou quase 100mil linhas no banco, gostaria de tentar um desempenho melhor, alguém sabe como eu posso conseguir isso?
Teria como eu enviar diversas linhas para um vetor e adicionalas de uma vez só no banco? Preciso conseguir algo mais rapido.

ViniGodoy

Oi. Primeiro de tudo. Aprenda a usar um profiler. Ele identifica gargalos de tempo e de memória facilmente. O Netbeans tem um.

Outra coisa. Ao invés de enviar um comando por vez no SQL, é mais eficiente enviar todos de uma vez só.
Use os método addBatch e batchUpdate, da classe PreparedStatement.

S

Problema é, se eu esperar carregar todos os arquivos sem dar o ps.close(); terei problema com a memória, eu posso então enviar por exemplo de 5k em 5k de linha e dar o batchUpdate();?

ViniGodoy

Quantos MB tem esse seu arquivo?

Acho que vc não vai ter grandes problemas não. Antes vc não fechava a conexão, mas mandava centenas de updates, o que é um desperdício absurdo de recursos. Com o batchUpdate, vc vai rodar uma única consulta, o que geralmente é muitíssimo mais leve.

Se seu arquivo for muito grande, aí bole a lógica para ler de pouco em pouco.

S

O arquivo tem uns 150mb em txt.

ViniGodoy

Então, mas sua VM tá autorizada a usar mais de 400! Daria para carregar o arquivo inteiro na memória! 2x!

Mas tenta lá com o batchUpdate. É provável que não estoure memória. Rodar updates aos poucos realmente consome muitos recursos.

Se ainda não funcionar, usa um profiler para descobrir onde essa memória tá indo… Não deveria estar estourando.
Na pior das hipóteses, leia de 50MB em 50MB.

Não tem pq também fazer em doses tão pequenas. Quanto menos execute(), mais rápido.

S

Bom, coloquei o addBatch(); e estorou a memoria bem rapido.
Pode me dizer se está certo o comando pra abrir o netbeans com 1gb?

“C:\Arquivos de programas\NetBeans 6.0.1\bin\netbeans.exe” -vm C:\Arquivos de programas\Java\jdk1.6.0_04\jre\bin\javaw.exe -vmargs -Xms1000m -Xmx1001m

Nunca usei isso e coloquei ontem sem saber se estava realmente certo. Bom que dessa vez pelomenos ele estorou a memória bem rapido, nao demorou 5 minutos como da ultima vez.

ViniGodoy

Use o profiler para identificar onde está o erro.

ViniGodoy

Só para confirmar… primeiro vc deu todos os addBatch… para só depois dar um único batchUpdate, certo?

S

Vou colocar o código como tá, eu leio primeiro todo o arquivo, vou dando o addBatch(); e quando ele fecha o arquivo, antes de terminar a conecção com o banco eu dou o batchUpdate();

public janelaPrincipal() {
            getConnection();
            getTabela();
            System.exit(0);
        
        
    }

    public static void getTabela(){
        try{

        File f = new File("Local");

        if ( f.exists() ){

                FileReader fr = new FileReader( f );
                BufferedReader leitor = new BufferedReader(fr);
                String linha;
                        do{
                                linha = leitor.readLine();
                                quebrarLinha(linha);	
                    }while(linha!=null);
                        leitor.close();
                        ps.executeBatch();
                        ps.close();
                        conn.close();
                }	
        }
        catch(IOException ex){
            System.out.println("Problema ao iniciar o arquivo");
        }
        catch(Exception e){  
              e.printStackTrace();  
        }
    }
    public static void quebrarLinha(String linha){
        if(linha!=null){
            String[] vetor = linha.split("\t");
            popularBanco(vetor);
        }
    }
    public static void popularBanco(String[] vetor){
        try{
            String importar = "INSERT INTO dar_tr_stroke VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
            ps = conn.prepareStatement(importar);
            for(int i=0; i<vetor.length; i++){
                ps.setString(i+1, vetor[i]);
            }
            ps.addBatch();
        }
        catch(SQLException ex){
            ex.printStackTrace();
            System.out.println("Impossivel de se inserir");
        }
    }
   public static Connection getConnection(){  
      try{  
         Class.forName("com.mysql.jdbc.Driver");  
         conn = DriverManager.getConnection(dbUrl,user,password);  

       }catch(Exception e){  
          e.printStackTrace();  
          System.out.println("Não foi possível se conectar");
    }  
       return conn;  
    }    
   
    private static String dbUrl="jdbc:mysql://localhost:3306/meuServer";  
    private static String user="root";  
    private static String password="1234";  
    private static Connection conn;
    private static PreparedStatement ps;
S

Tá ficando foda, nao sei o que fazer.
Tentei rodar o profile do netbeans, ele afirma algo dessa forma:

http://img237.imageshack.us/img237/5425/testeeegv8.jpg

Tentei tb adicionar essas linhas no programa pra tentar quebrar a rotina pouco a pouco:

public static void getTabela(){
        try{

        File f = new File("C:\Documents and Settings\Diego Chohfi\Desktop\ByDiogo\stroke.2007.12.txt");

        if ( f.exists() ){

                FileReader fr = new FileReader( f );
                BufferedReader leitor = new BufferedReader(fr);
                String linha;
                        do{
                                linha = leitor.readLine();
                                quebrarLinha(linha);
                                totalArquivos++;
                                if(totalArquivos>=400){
                                    ps.executeBatch();
                                    ps.close();
                                    totalArquivos=0;
                                }
                    }while(linha!=null);
                        leitor.close();
                        int[] totalAdicionados = ps.executeBatch();
                        System.out.println(totalAdicionados);
                        
                        ps.close();
                        conn.close();
                }	
        }

E mesmo assim nada, ele roda 4 segundo e já cai em error. Nao sei o que fazer.

ViniGodoy

Você pode colocar a exceção toda de OutOfMemoryError que vc recebe? Ela destaca alguma linha entre suas classes?

S

aqui ó

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
        at java.util.jar.Manifest$FastInputStream.<init>(Manifest.java:315)
        at java.util.jar.Manifest$FastInputStream.<init>(Manifest.java:310)
        at java.util.jar.Manifest.read(Manifest.java:178)
        at java.util.jar.Manifest.<init>(Manifest.java:52)
        at java.util.jar.JarFile.getManifestFromReference(JarFile.java:165)
        at java.util.jar.JarFile.getManifest(JarFile.java:146)
        at sun.misc.URLClassPath$JarLoader$2.getManifest(URLClassPath.java:693)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:221)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:430)
        at com.mysql.jdbc.PreparedStatement.getInstance(PreparedStatement.java:553)
        at com.mysql.jdbc.ConnectionImpl.clientPrepareStatement(ConnectionImpl.java:1378)
        at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4143)
        at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4042)
        at janelaPrincipal.popularBanco(janelaPrincipal.java:92)
        at janelaPrincipal.quebrarLinha(janelaPrincipal.java:86)
        at janelaPrincipal.getTabela(janelaPrincipal.java:60)
        at janelaPrincipal.<init>(janelaPrincipal.java:13)
        at janelaPrincipal$1.run(janelaPrincipal.java:42)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)

Não chegou a mostrar nada, só essa mensagem.

ViniGodoy

Você pode postar o seu método:
janelaPrincipal.popularBanco(janelaPrincipal.java:92)

Inteiro e destacar a linha 92?

S
public static void popularBanco(String[] vetor){
        String importar = "INSERT INTO dar_tr_stroke VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
        try{
            ps = conn.prepareStatement(importar);//destacado aqui;
            for(int i=0; i<vetor.length; i++){
                ps.setString(i+1, vetor[i]);
            }
            ps.addBatch();
        }
        catch(SQLException ex){
            ex.printStackTrace();
            System.out.println("Impossivel de se inserir");
        }
    }
ViniGodoy

Você só precisa chamar o prepareStatement uma vez.
Apenas o addBatch tem que estar no loop.

A idéia do BatchStatement é vc rodar várias queries num único statement. Aliás, por isso ele é tão rápido e gasta pouca memória. Você manda para o banco uma query só. Ele pré-compila e depois trabalha só com dados binários. :wink:

Tente mudar isso, e daí mandar o seu arquivo inteiro. Sem fazer 400 por vez. Deve funcionar.

Aliás, desculpe, eu devia ter visto o erro de cara. O código estava ali e eu me liguei pouco antes do seu último comment. :frowning:

ViniGodoy
Olhando aquele código completo anterior ali, acho que basta mover as linhas:

String importar = INSERT INTO dar_tr_stroke VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);;

ps = conn.prepareStatement(importar);

Para antes do do…while.

S

Fiz desta forma:

if ( f.exists() ){
                FileReader fr = new FileReader( f );
                BufferedReader leitor = new BufferedReader(fr);
                String linha;
                ps = conn.prepareStatement("INSERT INTO dar_tr_stroke VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);");//adicionei esta linha no meu getTabela();
                        do{
                            linha = leitor.readLine();
                            quebrarLinha(linha);
                    }while(linha!=null);
                        leitor.close();
                        ps.close();
                        conn.close();
                }	
        }

E o meu populaBanco() ficou desta forma:

public static void popularBanco(String[] vetor){
        try{
            for(int i=0; i<vetor.length; i++){
                ps.setString(i+1, vetor[i]);
            }
            ps.addBatch();
        }
        catch(SQLException ex){
            ex.printStackTrace();
            System.out.println("Impossivel de se inserir");
        }
    }

Porém ainda da o erro;

Exception in thread "AWT-EventQueue-0" 
java.lang.OutOfMemoryError: Java heap space
        at com.mysql.jdbc.SingleByteCharsetConverter.toBytesWrapped(SingleByteCharsetConverter.java:250)
        at com.mysql.jdbc.StringUtils.getBytesWrapped(StringUtils.java:554)
        at com.mysql.jdbc.PreparedStatement.setString(PreparedStatement.java:4093)
        at janelaPrincipal.popularBanco(janelaPrincipal.java:83)
        at janelaPrincipal.quebrarLinha(janelaPrincipal.java:77)
        at janelaPrincipal.getTabela(janelaPrincipal.java:60)
        at janelaPrincipal.<init>(janelaPrincipal.java:13)
        at janelaPrincipal$1.run(janelaPrincipal.java:42)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
CONSTRUÍDO COM SUCESSO (tempo total: 11 segundos)

//onde a linha 83 é 
ps.setString(i+1, vetor[i]);

Pelomenos dessa vez rodou um pouco mais, mas da mesma forma travou.
Estranho… Vlw pela ajuda que tu ta dando vini.

S

Cara, coloquei um contador pra dar o executeBatch(); a cada 5k de linhas.
Ele le as linhas absurdamente rápido, o problema ta na hora de executar, ele ta lento de mais, muito lento mesmo. Pior que antes quando eu usava o ps.update(); será que fiz algo errado?

ps = conn.prepareStatement("INSERT INTO dar_tr_stroke VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);");
                        do{
                            linha = leitor.readLine();
                            quebrarLinha(linha);
                            totalLinhas++;
                            System.out.println(totalLinhas);
                            if(totalLinhas==5000){
                                ps.executeBatch();
                                totalLinhas=0;
                                ps.close();
                                ps = conn.prepareStatement("INSERT INTO dar_tr_stroke VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);");
                            }
                    }while(linha!=null);
ViniGodoy

O gargalo de performance agora deve estar no seu banco de dados. Não interessa em que linguagem vc desenvolva.
Me diz uma coisa, que banco de dados é?

Não existe driver nativo para ele em Java? Tem que ser por JDBC?

S
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import java.io.*;
import java.sql.DriverManager;
import java.sql.SQLException;

    public janelaPrincipal() {
            getConnection();
            getTabela();
            System.exit(0);
        
        
    }
    public static void getTabela(){
        try{

        File f = new File("C:\Documents and Settings\Diego Chohfi\Desktop\ByDiogo\stroke.2007.12.txt");

        if ( f.exists() ){
                FileReader fr = new FileReader( f );
                BufferedReader leitor = new BufferedReader(fr);
                String linha;
                ps = (PreparedStatement) conn.prepareStatement("INSERT INTO dar_tr_stroke VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);");
                        do{
                            linha = leitor.readLine();
                            quebrarLinha(linha);
                            totalLinhas++;
                            System.out.println(totalLinhas);
                            if(totalLinhas==30000){
                                ps.executeBatch();
                                ps.clearBatch();
                                totalLinhas=0;
                            }
                    }while(linha!=null);
                        leitor.close();
                        ps.executeBatch();
                        ps.close();
                        conn.close();
                }	
        }
        catch(IOException ex){
            System.out.println("Problema ao iniciar o arquivo");
        }
        catch(Exception e){  
              e.printStackTrace();  
        }
    }
    public static void quebrarLinha(String linha){
        if(linha!=null){
            String[] vetor = linha.split("\t");
            popularBanco(vetor);
        }
    }
    public static void popularBanco(String[] vetor){
        try{
            for(int i=0; i<vetor.length; i++){
                ps.setString(i+1, vetor[i]);
            }
            ps.addBatch();
        }
        catch(SQLException ex){
            ex.printStackTrace();
            System.out.println("Impossivel de se inserir");
        }
    }
   public static void getConnection(){  
      try{  
        Class.forName("com.mysql.jdbc.Driver");  
        conn = (Connection) DriverManager.getConnection(dbUrl,user,password);  
       }catch(Exception e){  
          e.printStackTrace();  
          System.out.println("Não foi possível se conectar");
    }    
    }    
   
    private static String dbUrl="jdbc:mysql://localhost:3306/meuServer";  
    private static String user="root";  
    private static String password="1234";  
    private static Connection conn;
    private static PreparedStatement ps;
    private static int totalLinhas=0;
joaosavio

150mb em txt! É coisa pra caramba em

rolemberg

pq vc não vejo o leito depois de executa o seguinte comando: ps.executeBatch();??? e vou te fazer outra pegunta, pq de vez vc usar vetor não usa uma Collection, preenche toda ela e depois faz o insert no banco de dados???pq vejo que deste jeito que o codigo esta vc esa executando um por vez e assim o comando addBatch, não esta funcionando como devia…bem isso é o que estou vendo se estiver errado me corrijam…

abraço

ViniGodoy

É, nada a ver o que vc falou… Carregar o arquivo numa collection e depois do PreparedStatement só vai duplicar o espaço que ele ocupa na
memória.

O addBatch também não executa nada. Só quem executa o batch inteiro, numa única operação é o executeBatch() e isso ele só faz poucas vezes.

rolemberg

humm, ok peço desculpa pela resposta…

ViniGodoy

Sem problemas. Cai esse tipo de coisa na SCJP que vc vai fazer?

S

Vou testar o programa hj na empresa, com a ajuda do vini consegui deixa-lo o melhor que consegui.
Tem ideia que o programa em C que tem aqui populou 6 anos de arquivos em txt (1gb de arquivo, em txt!) em apenas 2horas.

Espero conseguir a mesma coisa com java hehe.

Criado 8 de abril de 2008
Ultima resposta 10 de abr. de 2008
Respostas 31
Participantes 6