Estouro na memoria do Heap

5 respostas
S

Eu ja postei uma vez com esse problema e codigo mas foi a muito tempo, e para naos er coveiro resolvi postar denovo e como meu codigo com algumas diferenças

Bom meu problema é o seguinte, a memoria do heap esta estouranda depois do meu programa rodar por umas 1 hora e meia. Como é uma mesma rotina que ele esta rodando sempre sem variar o numero de dados utilizados, suponho eu que a esta vazando memoria. Mas eu nao tenho ideia onde... Antes de postar o codigo vou explicar mais ou menos como ele funciona. É um programa para armazenar dados duranto o dia todo do WTR da BMF. Quando eu inicio o programa abre uma janela com 3 botoes, conecta, ON e OFF. Quando voce aperta o botao Conecta ele abre 2 IEs navega ate os respectivos sites e loga nos mesmos. Quando voce aperta ON ele inicia a rotina, e OFF desliga a rotina. A rotina esta rodando um um Thread separado para poder ser ligado e desligado inumeras vezes. Ok agora a rotina funciona mais ou menos assim. Ele da um refresh nos 2 IEs e armazena os dados coletados de tabelas em 2 matrizes, sendo que esses dados sao armazenados de um modo diferente que mostrado no site. Depois ele preenche uma linha de um txt chamado Ofertas.txt com o horario, ultimo negocio, e ofertas de compra e venda do ativo em questao. E armazena em outro txt chamado nlinhas.txt o numero atual de linhas do txt Ofertas.txt (esses txt serao utilizados em um programa C mais para frente mas isso nao vem ao caso). Depois disso ele reinicia a rotina. Essa rotina dura em torno de 10 segundos. O meu codigo é o seguinte:

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

/*
 * MMMInterface.java
 *
 * Created on Jan 4, 2009, 12:05:15 PM
 */
package mmk.mmminterface;

import java.io.*;
import java.util.*;
import java.text.*;
import net.sf.jiffie.*;

public class MMMInterface extends javax.swing.JFrame {

    /** Creates new form MMMInterface */
    public MMMInterface() {
        initComponents();
        new Conecta().start();


    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jPasswordField1 = new javax.swing.JPasswordField();
        jTextField1 = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jTextField2 = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        jTextField3 = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Monkey Money Maker 1.0");
        setAlwaysOnTop(true);
        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

        jLabel1.setText("LOGIN");

        jLabel2.setText("SENHA");

        jButton1.setText("CONECTA");
        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton1MouseClicked(evt);
            }
        });

        jButton2.setText("OFF");
        jButton2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton2MouseClicked(evt);
            }
        });

        jButton3.setText("ON");
        jButton3.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jButton3MouseClicked(evt);
            }
        });

        jTextField2.setEditable(false);
        jTextField2.setFont(new java.awt.Font("Tahoma", 0, 28));
        jTextField2.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        jTextField2.setText("0");

        jLabel3.setFont(new java.awt.Font("Tahoma", 0, 36)); // NOI18N
        jLabel3.setForeground(new java.awt.Color(102, 102, 102));
        jLabel3.setText("P&L");

        jTextField3.setBackground(new java.awt.Color(255, 0, 0));
        jTextField3.setEditable(false);
        jTextField3.setFont(new java.awt.Font("Tahoma", 1, 18));
        jTextField3.setHorizontalAlignment(javax.swing.JTextField.CENTER);
        jTextField3.setText("OFF");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(28, 28, 28)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2)))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jLabel3)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jTextField2, javax.swing.GroupLayout.DEFAULT_SIZE, 123, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 123, Short.MAX_VALUE)
                        .addComponent(jPasswordField1)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 69, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jTextField3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 81, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jButton2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jButton3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addGap(30, 30, 30))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 57, Short.MAX_VALUE)
                    .addComponent(jTextField2, javax.swing.GroupLayout.DEFAULT_SIZE, 57, Short.MAX_VALUE)
                    .addComponent(jLabel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 57, Short.MAX_VALUE))
                .addGap(3, 3, 3)
                .addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel1))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel2)
                            .addComponent(jPasswordField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(22, 22, 22))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jButton3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton2)
                        .addContainerGap())))
        );

        pack();
    }// </editor-fold>                        

    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {                                      
        conectado = true;
    }                                     

    private void jButton3MouseClicked(java.awt.event.MouseEvent evt) {                                      
        ligado = true;
        jTextField3.setText("ON");
        jTextField3.setBackground(new java.awt.Color(0, 163, 0));
    }                                     

    private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {                                      
        ligado = false;
        jTextField3.setText("OFF");
        jTextField3.setBackground(new java.awt.Color(255, 0, 0));
    }                                     

    class Conecta extends Thread {

       
        public void run() {

            try {
                while (!conectado) {
                }

                if (conectado) {

                    //Declaraçao das Matrizes das Ofertas
                    int mofc[][];
                    mofc = new int[6][4];
                    int mofv[][];
                    mofv = new int[6][4];
                    int cont1;
                    int cont2;
                    //Declaracao dos IEs
                    InternetExplorer k = new InternetExplorer();
                    InternetExplorer k2 = new InternetExplorer();
                    //Inicia os IEs
                    k.setVisible(true);
                    k2.setVisible(true);
                    //Instancia a Data
                    Date time = new Date();
                    
                    //Instancia as variaveis para armazenar os objetos a serem utilizados do IE
                    IHTMLFrameElement frame;
                    IHTMLDocument2 frameDocument;
                    ElementList tab2;
                    IHTMLTable tabe;
                    ElementList tab;
                    IHTMLTable ofc;
                    IHTMLTable ofv;
                    
                    //Buffer para ler o numero de linhas do txt nlinhas
                    BufferedReader in;
                    String snl;
                    
                    PrintStream escrever1;

                    int nl;
                    
                    //Faz os IEs navegarem para os seus respectivos sites
                    k.navigate("https://wtr.bmf.com.br/Autenticacao/SMLoginIBroker.fcc?TYPE=33554433&REALMOID=06-0ea14422-cef7-4d33-b467-0734805081ef&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=$SM$Rlq1KK%2bTjmanrmkO%2bWkztYGagAIeD0fRFWN4cb08AryeECePlRWNZcA%2b3YdN0qOL&TARGET=$SM$HTTPS%3a%2f%2fwtr%2ebmf%2ecom%2ebr%2fnegociacao%2facompanhamento_de_mercado%2fcotacoes%2fcotacaoAllBook%2easp%3fempresa%3dCD%26instrumento%3dwinm09");
                    k.waitWhileBusy();
                    IHTMLDocument2 document = k.getDocument(true);

                    k2.navigate("https://wtr.bmf.com.br/Autenticacao/SMLoginIBroker.fcc?TYPE=33554433&REALMOID=06-0ea14422-cef7-4d33-b467-0734805081ef&GUID=&SMAUTHREASON=0&METHOD=GET&SMAGENTNAME=$SM$Rlq1KK%2bTjmanrmkO%2bWkztYGagAIeD0fRFWN4cb08AryeECePlRWNZcA%2b3YdN0qOL&TARGET=$SM$HTTPS%3a%2f%2fwtr%2ebmf%2ecom%2ebr%2fnegociacao%2facompanhamento_de_mercado%2fcotacoes%2easp%3fempresa%3dCD%26ativo%3dwinm09");
                    k2.waitWhileBusy();
                    IHTMLDocument2 document2 = k2.getDocument(true);
                    
                    //Loga nos 2 IEs
                    IHTMLInputElement input = (IHTMLInputElement) document.getElementByName("USER");
                    input.setValue("MEU LOGIN");
                    k.waitWhileBusy();
                    IHTMLInputElement input2 = (IHTMLInputElement) document.getElementByName("PASSWORD");
                    input2.setValue("MINHA SENHA");
                    k.waitWhileBusy();
                    IHTMLFormElement form = (IHTMLFormElement) document.getElementByName("LoginSM");
                    form.submit(true);
                    k.waitWhileBusy();

                    IHTMLInputElement input3 = (IHTMLInputElement) document2.getElementByName("USER");
                    input3.setValue("MEU LOGIN");
                    k2.waitWhileBusy();
                    IHTMLInputElement input4 = (IHTMLInputElement) document2.getElementByName("PASSWORD");
                    input4.setValue("MINHA SENHA");
                    k2.waitWhileBusy();
                    IHTMLFormElement form2 = (IHTMLFormElement) document2.getElementByName("LoginSM");
                    form2.submit(true);
                    k2.waitWhileBusy();
                    
                    //Instancia os arquivos a serem utilizados
                    File ofertas = new File("C://Ofertas.txt");
                    PrintStream escrever = new PrintStream(new FileOutputStream(ofertas, true));
                    File nlinhas = new File("C://nlinhas.txt");

                    int cont = 0;

                    String time2;
                    
                    //Rotina que deve rodar por 8 horas
                    while (true) {

                        if (ligado) {
                            
                            //Da refresh nos 2 IEs e espera ate ambos terminarem
                            k.refresh(true);
                            k2.refresh(true);
                            k2.waitWhileBusy();
                            k.waitWhileBusy();
                            //Armazena o frame a ser utilizado
                            frame = (IHTMLFrameElement) document2.getElementById("fmeLeft");
                            frameDocument = frame.getDocument(true);
                            //Armazena as tabelas a serem utilizadas
                            tab2 = frameDocument.getElementListByTag("table");
                            tabe = (IHTMLTable) tab2.get(0);
                            tab = document.getElementListByTag("table");

                            int i = 2;

                            ofc = (IHTMLTable) tab.get(5);
                            ofv = (IHTMLTable) tab.get(8);

                            k.waitWhileBusy();
                            //Abre o Buffer in
                            in = new BufferedReader(new FileReader(nlinhas));                         
                            snl = in.readLine();
                            //Fecha o Buffer in
                            in.close();
                            nl = Integer.parseInt(snl);
                            time = new Date();
                            //Formata o horario no formato necessario
                            time2 = new SimpleDateFormat("HH mm ss").format(time);

                            cont2 = 2;
                            cont1 = 0;
                            
                            //Armazena as ofertas de compra na matriz alocada por preço e nao mais por oferta
                            while (cont1 <= 4) {
                                mofc[cont1][0] = 1;
                                mofc[cont1][1] = Integer.parseInt(ofc.getRow(cont2 + cont1).getCell(3).getInnerText());
                                mofc[cont1][2] = Integer.parseInt(ofc.getRow(cont2 + cont1).getCell(4).getInnerText().replace(".", ""));
                                while (cont2 + cont1 <= ofc.getRowCount() - 1 && Integer.parseInt(ofc.getRow(cont2 + cont1).getCell(4).getInnerText().replace(".", "")) == Integer.parseInt(ofc.getRow(cont2 + cont1 + 1).getCell(4).getInnerText().replace(".", ""))) {
                                    cont2 = cont2 + 1;
                                    mofc[cont1][0] = mofc[cont1][0] + 1;
                                    mofc[cont1][1] = mofc[cont1][1] + Integer.parseInt(ofc.getRow(cont2 + cont1).getCell(3).getInnerText());
                                }
                                cont1 = cont1 + 1;
                            }
                            cont2 = 2;
                            cont1 = 0;
                            
                            //Armazena as ofertas de venda na matriz alocada por preço e nao mais por oferta
                            while (cont1 <= 4) {
                                mofv[cont1][0] = 1;
                                mofv[cont1][1] = Integer.parseInt(ofv.getRow(cont2 + cont1).getCell(3).getInnerText());
                                mofv[cont1][2] = Integer.parseInt(ofv.getRow(cont2 + cont1).getCell(4).getInnerText().replace(".", ""));
                                while (cont2 <= ofv.getRowCount() - 1 && Integer.parseInt(ofv.getRow(cont2 + cont1).getCell(4).getInnerText().replace(".", "")) == Integer.parseInt(ofv.getRow(cont2 + cont1 + 1).getCell(4).getInnerText().replace(".", ""))) {
                                    cont2 = cont2 + 1;
                                    mofv[cont1][0] = mofv[cont1][0] + 1;
                                    mofv[cont1][1] = mofv[cont1][1] + Integer.parseInt(ofv.getRow(cont2 + cont1).getCell(3).getInnerText());
                                }
                                cont1 = cont1 + 1;
                            }



                            //Preenche a linha do txt Ofertas
                            escrever.print(time2 + " ");
                            escrever.print(tabe.getRow(0).getCell(0).getInnerText().substring(47, 53) + " ");
                            i = 0;
                            while (i <= 4) {

                                //escrever.print(ofc.getRow(i).getCell(3).getInnerText() + " " + ofc.getRow(i).getCell(4).getInnerText() + " ");
                                escrever.print(mofc[i][0] + " " + mofc[i][1] + " " + mofc[i][2] + " ");

                                i = i + 1;
                            }
                            i = 0;
                            while (i <= 3) {

                                //escrever.print(ofv.getRow(i).getCell(3).getInnerText() + " " + ofv.getRow(i).getCell(4).getInnerText() + " ");
                                escrever.print(mofv[i][0] + " " + mofv[i][1] + " " + mofv[i][2] + " ");

                                i = i + 1;

                            }


                            // escrever.println(ofv.getRow(21).getCell(3).getInnerText() + " " + ofv.getRow(21).getCell(4).getInnerText());
                            escrever.println(mofv[4][0] + " " + mofv[4][1] + " " + mofv[4][2] + " ");

                            nl = nl + 1;
                            //Abre o printstream escrever1
                            escrever1 = new PrintStream(new FileOutputStream(nlinhas, false));
                            
                            //Escreve no txt nlinhas o numero de linhas atual
                            escrever1.println(nl);
                            
                            //Fecha o printsream escrever1
                            escrever1.close();
                            cont = cont + 1;

                        //this.sleep(3000);
                        }
                    }

                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                MMMInterface mmm = new MMMInterface();
                mmm.setIconImage(mmm.getToolkit().getImage("C://monkey.gif"));
                mmm.setVisible(true);

            }
        });
    }
    public static boolean ligado = false;
    public static boolean conectado = false;

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPasswordField jPasswordField1;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;
    private javax.swing.JTextField jTextField3;
    // End of variables declaration                   
}

PS: Esse programa nao sera destribuido ou vendido, sera apenas para uso proprio.

5 Respostas

ViniGodoy

Use um profiler para descobrir onde está o problma.

Também é uma boa para rodar o programa com a seguinte opção na VM:
-XX:+HeapDumpOnOutOfMemoryError

Isso fará que o Java gere um arquivo de dump da memória (.dmp), antes de sua aplicação falhar pelo OutOfMemoryError. Esse dump vc pode abrir no profiler do Netbeans, e ver exatamente onde o problema está.

S

Bom eu nao gerei a dump, mas pelo profiler do netbeans eu pude ver que o que ta vazando memeoria seriam o java.lang.ref.Finalizer, o java.util.HashMap$Entry e o java.util.HashMap$Entry[]. Os dois primeiros estao em disparado usando mais bytes… Alguma ideia dado essa informacao?

ViniGodoy

Ligue a opção de rastrear as alocações no Stack. Uma boa também é abrir as instâncias do entry e ver que objeto está associado a elas. Normalmente, no caso de leaks, vc verá repetições centenas de vezes da mesma classe.

Por fim, procure também o local onde esses mapas são usados no seu código, em que rotina são chamados, etc.

S

Eu nao sei fazer nenhuma das duas coisas haha… alguma indicaçao de como fazer?

vlew!!

S

Entao … eu nao consegui essa opcao de rastrar as alocacoes do stack… onde ela fica no NetBeans? Como eu vejo as isntancias do entry?

Esses mapas devem tar sendo utilizados numa API que eu uso chamada juffie… que usa uma outra chamada Jacob que meche com JNI. Eu usso isso para pegar informacoes de um IE…

Criado 30 de abril de 2009
Ultima resposta 6 de mai. de 2009
Respostas 5
Participantes 2