PreparedStatement e OutOfMemoryError (java heap)

9 respostas
hacebe

pessoal, depois de algumas entradas de dados no aplicativo:

Exception in thread "Thread-42" 
java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:2894)
        at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:117)
        at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:614)
        at java.lang.StringBuilder.append(StringBuilder.java:229)
        at geomap.PrincipalSecretaria.carregaPendencias(PrincipalSecretaria.java:3780)
        at geomap.frmAbreProjeto.setAlterado(frmAbreProjeto.java:2044)
        at geomap.frmAbreProjeto$38.run(frmAbreProjeto.java:1583)
Exception in thread "Timer-0" 
java.lang.OutOfMemoryError: Java heap space
        at java.lang.ClassLoader.findLoadedClass0(Native Method)
        at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:939)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:316)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
        at java.util.ResourceBundle$RBClassLoader.loadClass(ResourceBundle.java:463)
        at java.util.ResourceBundle$Control.newBundle(ResourceBundle.java:2401)
        at java.util.ResourceBundle.loadBundle(ResourceBundle.java:1424)
        at java.util.ResourceBundle.findBundle(ResourceBundle.java:1383)
        at java.util.ResourceBundle.findBundle(ResourceBundle.java:1310)
        at java.util.ResourceBundle.findBundle(ResourceBundle.java:1310)
        at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1252)
        at java.util.ResourceBundle.getBundle(ResourceBundle.java:850)
        at sun.util.resources.LocaleData$1.run(LocaleData.java:142)

        at java.security.AccessController.doPrivileged(Native Method)
        at sun.util.resources.LocaleData.getBundle(LocaleData.java:140)
        at sun.util.resources.LocaleData.getDateFormatData(LocaleData.java:128)
        at java.text.DateFormatSymbols.cacheLookup(DateFormatSymbols.java:595)
        at java.text.DateFormatSymbols.initializeData(DateFormatSymbols.java:604)
        at java.text.DateFormatSymbols.<init>(DateFormatSymbols.java:140)

        at java.text.DateFormatSymbols.getInstance(DateFormatSymbols.java:314)
        at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:498)
        at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:475)
        at geomap.PrincipalSecretaria.atualizaListaServicos(PrincipalSecretaria.java:2660)
        at geomap.PrincipalSecretaria$Reminder.run(PrincipalSecretaria.java:510)
        at java.util.TimerThread.mainLoop(Timer.java:550)
        at java.util.TimerThread.run(Timer.java:500)
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
meu código é o seguinte:
try {
                    java.util.Date date = new java.util.Date();
                    SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd");
                    SimpleDateFormat calendar = new SimpleDateFormat("HH:mm");

                    PreparedStatement ps1;
                    ps1 = conn.prepareStatement("UPDATE tab_providencias SET TP_PROVIDENCIA=?, TP_SITUACAO=?, TP_DATA=?, TP_PENDENTE=?, TP_ORIGEM=?, TP_PROPRIETARIO=? WHERE TP_CODIGO = ?");
                    ps1.setString(1, jComboBox4.getSelectedItem().toString());
                    ps1.setString(2, jTextField1.getText());
                    ps1.setString(3, reformataData(hoje));
                    ps1.setBoolean(4, true);
                    ps1.setInt(5, GeomapView.codigoUsuario);

                    ps1.setBoolean(6, jCheckBox4.isSelected());
                    ps1.setInt(7, idProvidenciaGeo);

                    ps1.executeUpdate();
                    ps1.close();
                    idProvidenciaGeo = 0;

                    novaProvidencia();
                    pegaProvidencias();
                    setAlterado();
                /* PreparedStatement ps;
                ps = conn.prepareStatement("UPDATE tab_providencias SET TP_PROVIDENCIA=?, TP_DATA=?, TP_PENDENTE=? WHERE TP_CODIGO = ?");
                ps.setString(1, jComboBox4.getSelectedItem().toString());
                ps.setString(2, reformataData(hoje));
                ps.setBoolean(3, jCheckBox4.isSelected());
                ps.setInt(4, idProvidenciaGeo);
                ps.execute();
                ps.close();
                novaProvidencia();
                pegaProvidencias();  */

                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }catch(Out...

Pessoal, percebi que a cada vez que incluo dados no BD, o programa consome uns 2MB em média por seguido e chega a mostrar!

O que pode ser?
obriagado!

9 Respostas

K

Você já tentou limitar o uso da memória com os parâmetros -Xmx256m -Xms256m ?

hacebe

já sim amigo!

E nao adianta… to tentando colocar o gc pra ficar passando toda hora, mas chega em um estado que ele nao libera a memoria, mas dá uma ligeira melhorada!

Obrigado por responder!

nbluis

Cara, ta parecendo que teu problema é aqui

at geomap.PrincipalSecretaria.carregaPendencias(PrincipalSecretaria.java:3780)

Esse

at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:117)

Pode ser um sinal.

O que vc ta colocando nesse StringBuilder ?

hacebe

amigo, eu to usando o netbeans 6.1

eu nao mexi a fundo nesse arquivo nao…
só coloquei aquilo la!

[:(]

Obrigado

ramilani12

Provavelmente seu erro esteja aqui:

at geomap.PrincipalSecretaria.carregaPendencias(PrincipalSecretaria.java:3780)  
at geomap.frmAbreProjeto.setAlterado(frmAbreProjeto.java:2044)

O que faz este dois metodos?

fantomas

Você pode postar a classe PrincipalSecretaria dizendo qual é a linha 3780?

ramilani12

ramilani12:
Provavelmente seu erro esteja aqui:

at geomap.PrincipalSecretaria.carregaPendencias(PrincipalSecretaria.java:3780)  
at geomap.frmAbreProjeto.setAlterado(frmAbreProjeto.java:2044)

O que fazem estes dois metodos?

hacebe

Bom dia,

O método carregaPendencias lista itens do banco de dados e coloca dentro de um tableModel

void carregaPendencias(){
        try{          
            DefaultTableModel modelo2 = new DefaultTableModel(){
                @Override
                public boolean isCellEditable(int mCol,int cCol){
                    return false;
                }
            };
            modelo2.addColumn("ID", new Object[]{});
            modelo2.addColumn("Cliente", new Object[]{});
            modelo2.addColumn("Fazenda", new Object[]{});
            modelo2.addColumn("Município", new Object[]{});
            
             
            Statement stmt2 = conn.createStatement();
            
            ResultSet rs2 = null;
            if((!jCheckBox1.isSelected()) && (!jCheckBox2.isSelected())){
                
                rs2 = stmt2.executeQuery(defaultQueryGeo);
            }else{
                boolean chkUser = false;
                String subQuery = "";
                if(jCheckBox1.isSelected() == true){
                    chkUser = true;
                    subQuery += " TP_ENCARREGADO = '"+ utils.pegaUsuario(jComboBox1.getSelectedItem().toString()) +"' and ";
                }else{
                    chkUser = false;
                    subQuery += " TP_ENCARREGADO != 0 and ";
                }
                if(jCheckBox2.isSelected() == true){

                    subQuery += " TP_CODIGO_CLIENTE ='" + utils.pegaCliente(jComboBox2.getSelectedItem().toString()) + "'";
                                        if(chkUser){
                        subQuery += " and ";
                    }
                }
                //String query = "SELECT DISTINCT TP_TP_CODIGO FROM tab_providencias, tab_projetos WHERE tab_projetos.TP_CODIGO = tab_providencias.TP_TP_CODIGO and tab_projetos.TP_VISIVEL = 1 and tab_providencias.TP_PENDENTE = 1 and tab_providencias.TP_PROPRIETARIO = 0 and " + subQuery;
//                String query = "SELECT distinct tab_projetos.TP_CODIGO, tab_projetos.TP_ALTERADO, tab_projetos.TP_CODIGO_CLIENTE, tab_fazendas.TF_MUNICIPIO FROM tab_projetos, tab_fazendas, tab_grupo_imoveis WHERE "+ subQuery +" and TP_VISIVEL=1 and TF_CODIGO = tab_projetos.TP_CODIGO_FAZENDA and tab_grupo_imoveis.TGI_TP_CODIGO = tab_projetos.TP_CODIGO and tab_grupo_imoveis = tab_fazendas.TF_CODIGO  GROUP BY TP_CODIGO";
                String query = "SELECT distinct tab_projetos.TP_CODIGO, tab_projetos.TP_ALTERADO, tab_projetos.TP_CODIGO_CLIENTE, tab_fazendas.TF_MUNICIPIO, TGI_CODIGO, TGI_TP_CODIGO FROM tab_projetos, tab_fazendas, tab_grupo_imoveis WHERE "+ subQuery +" TP_VISIVEL=1 and TP_CODIGO = TGI_TP_CODIGO and TF_CODIGO = TGI_TC_CODIGO GROUP BY TP_CODIGO";
                rs2 = stmt2.executeQuery(query);
                System.out.println(query);
		
                Statement stm3;
                ResultSet rs3;
                while(rs2.next()){  
                //System.out.println("loopping");
                stm3 = conn.createStatement();
                
                rs3 = stm3.executeQuery("SELECT * FROM tab_fazendas, tab_grupo_imoveis, tab_projetos WHERE TF_CODIGO = TGI_TC_CODIGO and TGI_TP_CODIGO = "+ rs2.getInt("TGI_TP_CODIGO") +" and TP_VISIVEL = 1  GROUP BY TF_NOME");
                String imoveis = "";
                while(rs3.next()){
                    
                    imoveis += rs3.getString("TF_NOME");
                    if(!rs3.isLast()){
                        imoveis += ", ";
                    }
                    //System.out.println(imoveis);
                    
                }
                System.out.println(imoveis);
                if(rs2.getInt(2) == 0){
                    //modelo2.addRow(new Object[]{rs2.getInt(1), utils.retornaCliente(rs2.getInt(3)), utils.retornaProjeto(rs2.getInt(1)), rs2.getString(4)});   
                    modelo2.addRow(new Object[]{rs2.getInt(1), utils.retornaCliente(rs2.getInt(3)), imoveis, rs2.getString(4)});   
                }else if(rs2.getInt(2) == 9999){
                    modelo2.addRow(new Object[]{rs2.getInt(1), utils.retornaCliente(rs2.getInt(3)), "<html><font color='#FF0000'><b>" + imoveis + "</b></font></html>", rs2.getString(4)});    

                }else if(rs2.getInt(2) != 0){
                    modelo2.addRow(new Object[]{rs2.getInt(1), utils.retornaCliente(rs2.getInt(3)), "<html><font color='#3b6cd0'><b>" + imoveis + "</b></body></html>", rs2.getString(4)});    
                
                }
                

            }
             
            }

            jTable3.setModel(modelo2);
            jTable3.setAutoResizeMode(jTable3.AUTO_RESIZE_OFF);
            jTable3.getColumnModel().getColumn(0).setPreferredWidth(30);
            jTable3.getColumnModel().getColumn(1).setPreferredWidth(110);
            jTable3.getColumnModel().getColumn(2).setPreferredWidth(110);
            jTable3.getColumnModel().getColumn(3).setPreferredWidth(150);
            
        
            //SELECT DISTINCT TP_TP_CODIGO FROM tab_providencias
            
        }catch(Exception e){
            System.out.println("erro: " + e.getMessage());
        }
        
    }

O método setAlterado, altera um valor boolean da tabela

public void setAlterado() {
        try {
            if (codResponsavel == GeomapView.codigoUsuario) {
                PreparedStatement ps = conn.prepareStatement("UPDATE tab_projetos SET TP_ALTERADO=1 WHERE TP_CODIGO = ?");

                ps.setInt(1, PrincipalSecretaria.codigoProjeto);

                ps.executeUpdate();
                ps.close();
                principal.carregaPendencias();
            }

        } catch (Exception e) {
            System.out.println("erro + " + e.getMessage());
        }
    }

Linha 3780:

rs3 = stm3.executeQuery("SELECT * FROM tab_fazendas, tab_grupo_imoveis, tab_projetos WHERE TF_CODIGO = TGI_TC_CODIGO and TGI_TP_CODIGO = "+ rs2.getInt("TGI_TP_CODIGO") +" and TP_VISIVEL = 1  GROUP BY TF_NOME");

Obrigado!

B

Alguns pontos pra vc fazer antes de voltar :slight_smile:

[list]ENTENDA o código q QUALQUER IDE gera pra você. Se você gerou automático, não creio que você vá conseguir muito debug sem antes entender o código.[/list]
[list]Coloque alguns Sysout para vc saber onde está o seu “calo”[/list]
[list]Tente usar Fetch on Demand no JDBC - para dar fetch por partes[/list]
[list]Qual o tamanho do ResultSet gerado pela query ? Uma tabela de 1.000.000.000 de registros não conseguirá ser carregada se vc usar -Xmx256M[/list]
[list]Customize o seu table model. Deixe de usar o DefaultTablModel e extenda o AbstractTableModel (é mais fácil que parece).[/list]

Enfim, creio que você tenha que da uma olhada no google sobre como customizar um table model.

Eu particularmente ADORO ferramentas que auxiliem o trabalho. MAs SEMPRE, digo SEMPRE, saiba fazer na mão antes de partir para algo automático.

Abraços

Criado 30 de julho de 2008
Ultima resposta 2 de ago. de 2008
Respostas 9
Participantes 6