Results 1 to 4 of 4
Like Tree1Likes
  • 1 Post By DarrylBurke

Thread: Database Table Model Does Not Release Memory When Disposed

  1. #1
    evan087 is offline Member
    Join Date
    Aug 2012
    Posts
    6
    Rep Power
    0

    Default Database Table Model Does Not Release Memory When Disposed

    Hi everyone,

    I have a large table which I would like to display using the table model code below. Unfortunately there seems to be a memory-leak of some kind and the memory allocated for the table does not get released after the frame is disposed.


    Database Table Model Does Not Release Memory When Disposed-scr.gif


    When the "Database Shower" frame is closed the memory does not get released as expected but stays the same. I have been looking for the culprit for hours now and would appreciate a push in the right direction. Please see code below..

    ________________________________________

    Java Code:
    package test;
    
    import com.sun.awt.AWTUtilities;
    import java.awt.Color;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridBagLayout;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import javax.swing.JButton;
    import javax.swing.JPanel;
    import javax.swing.JFrame;
    
    /**
     *
     * @author Evan
     */
    public class Test extends JFrame implements ActionListener{
        
        JButton jButton = new JButton("Open DB");
        JButton jButton2 = new JButton("Close DB");
        JPanel panel = new JPanel();
        Connection con;
        
        DatabaseShower frame;
        
        public Test()
        {
            getContentPane().setBackground(new Color(0, 0, 40, 190));
            setSize(400,400);
            setVisible(true);
            setLayout(new GridBagLayout());
            add(panel);
            
            jButton.addActionListener(this);
            jButton.setActionCommand("open db");
            
            jButton2.addActionListener(this);
            jButton2.setActionCommand("close db");
            
            panel.add(jButton);
            panel.add(jButton2);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            
            panel.setBounds(0,0,200,200);
        }         
        
        @Override
        public void paint(Graphics g)
        {
            Graphics2D g2d2 = (Graphics2D)g;
            g2d2.setColor(new Color(255,255,255,100));
            g2d2.fillRoundRect(getInsets().left + (getHeight()/200), getInsets().top + (getHeight()/200), getWidth() - (2*(getInsets().left + (getHeight()/200))), getHeight() - (2*(((getInsets().bottom + getInsets().top)) + (getHeight()/200))), 10, 10);
            
            panel.repaint();
        }     
        
        public void actionPerformed(ActionEvent e)
        {
            if (e.getActionCommand().equals("open db")) 
            {
                try{openDB();}catch(Exception f){}
            }    
            
            if (e.getActionCommand().equals("close db")) 
            {
                try{frame.data.removeAll(); frame.names.removeAll(); frame.data = null; frame.names = null; frame = null;}catch(Exception f){}
                try{con.close();}catch(Exception f){}
            }    
        }        
    
        public static void main(String[] args) 
        {
            // TODO code application logic here.
            java.awt.EventQueue.invokeLater(new Runnable() {
    
                public void run() {
                    new Test().setVisible(true);
                }
            });
        }
        
        public void openDB() throws Exception
        {
        Class.forName("org.firebirdsql.jdbc.FBDriver").newInstance();
        con = DriverManager.getConnection("jdbc:firebirdsql://localhost:3050/d:/database/pos.gdb", "SYSDBA", "masterke");
        String title = "Database Shower";
        frame = new DatabaseShower(con, title);
        frame.setSize(1024, 768);
        frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    }
    ______________________________________________

    Java Code:
    package test;
    
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.DefaultTableModel;
    import java.sql.*;
    
    public class DatabaseShower extends JFrame {
      protected JList names;
      protected JTable data = new JTable();
      public DatabaseShower(final Connection con, String title)
          throws SQLException {
        super(title);
        names = new JList(new TableNameListModel(con));
        names.addListSelectionListener(new ListSelectionListener() {
          public void valueChanged(ListSelectionEvent e) {
            if (!e.getValueIsAdjusting()) {
              Object tableName = names.getSelectedValue();
              if (tableName != null) {
                try {
                  data.setModel(new DatabaseTableModel(con, tableName));
                } catch (SQLException ex) {
                  ex.printStackTrace();
                  data.setModel(new DefaultTableModel());
                }
              }
            }
          }
        });
        getContentPane().add(new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
            new JScrollPane(names), new JScrollPane(data)));
      }
      
    }

    _________________________________________________

    Java Code:
    package test;
    
    import org.apache.commons.dbutils.*;
    import javax.swing.table.DefaultTableModel;
    import java.sql.*;
    import java.util.Vector;
    
    public class DatabaseTableModel extends DefaultTableModel {
      private final QueryRunner queryRunner = new QueryRunner();
      public DatabaseTableModel(Connection con, Object tableName)
          throws SQLException {
        // might need to delimit table names
        String sql = "SELECT * FROM " + tableName;
        queryRunner.query(con, sql, new ResultSetHandler() {
          public Object handle(ResultSet rs) throws SQLException {
            // extract the column names
            int numColumns = rs.getMetaData().getColumnCount();
            Vector column = new Vector();
            for (int i = 1; i <= numColumns; i++) {
              column.add(rs.getMetaData().getColumnName(i));
            }
            // extract the data
            Vector data = new Vector();
            while (rs.next()) {
              Vector row = new Vector();
              for (int i = 1; i <= numColumns; i++) {
                row.add(rs.getString(i));
              }
              data.add(row);
            }
            setDataVector(data, column);
            return null;
          }
        });
      }
    }
    ________________________________________________

    Java Code:
    package test;
    
    import javax.swing.*;
    import java.sql.*;
    import java.util.*;
    
    public class TableNameListModel extends AbstractListModel {
      private final List listData = new ArrayList();
      public TableNameListModel(Connection con) throws SQLException {
        ResultSet rs = con.getMetaData().getTables(null,null,null,null);
        // you might need a filter here if your database mixes system
        // tables with user tables, e.g. Microsoft SQL Server
        while (rs.next()) {
          listData.add(rs.getString("TABLE_NAME"));
        }
        rs.close();
      }
      public int getSize() { return listData.size(); }
      public Object getElementAt(int i) { return listData.get(i); }
    }

    __________________________________________________ _


    The database I am using is Firebird.


    Any help greatly appreciated..

  2. #2
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,452
    Rep Power
    20

    Default Re: Database Table Model Does Not Release Memory When Disposed

    The Task Manager isn't the right tool to check for a memory leak, simply because memory released by your running program may not be returned to the OS by the JVM.

    Use a profiler.

    db
    Tolls likes this.
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  3. #3
    evan087 is offline Member
    Join Date
    Aug 2012
    Posts
    6
    Rep Power
    0

    Default Re: Database Table Model Does Not Release Memory When Disposed

    Thanks for the response it was very helpful..

    It seems that the JVM is reluctant to let go of allocated memory and hangs on to it in case it might be needed again. I do not understand the full concept of it but in my particular case it is not ideal.

    I have chosen to take an alternative path and use one java application to open another as follows:

    Java Code:
    try
    {
            String[] command = {"javaw", "-jar", "D:\\netbeans\\test\\dist\\test.jar"};  
            Runtime runTime = Runtime.getRuntime();
            Process process = runTime.exec(command);
    } 
    
    catch (IOException f) 
    {
            f.printStackTrace();
    }
    This way the resources are returned once the second java application terminates.

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,183
    Rep Power
    20

    Default Re: Database Table Model Does Not Release Memory When Disposed

    You could look at the -XXMaxHeapFree as discussed here. This lets you control the maximum % of free heap the JVM will hold onto before shrinking. It defaults to 70%.
    Please do not ask for code as refusal often offends.

    ** This space for rent **

Similar Threads

  1. How to maximum release memory in StAX?
    By kingsz1 in forum XML
    Replies: 0
    Last Post: 07-18-2010, 01:50 AM
  2. Copy Default table model to another default table model?
    By greatmajestics in forum AWT / Swing
    Replies: 2
    Last Post: 04-28-2010, 05:08 PM
  3. Release Physical memory
    By Faisal Ahmed in forum New To Java
    Replies: 3
    Last Post: 03-24-2010, 02:37 PM
  4. Replies: 1
    Last Post: 01-08-2010, 07:19 AM
  5. Table model
    By Manfizy in forum NetBeans
    Replies: 4
    Last Post: 11-08-2008, 03:19 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •