serban.b serban.b - 5 months ago 20
Java Question

Java Release Resources

I'm having a problem with a code. In MainFrame.java I'm creating a new JDialog which loads a ResultSet from a derby database to a jTable. I've inserted 150000 rows in the database for testing purpose. Loading the values from ResultSet into jTable (in LoadTable() method), increases java.exe system resource memory about 500 mb.
The problem is when disposing the JDialog, the 500 mb used are not freed up. They are freed up only when calling system.exit() in MainFrame.java.

When I reopen the JDialog, the memoryresources increase up to 800mb. The 3rd reopen of the JDialog increase the memory up to 1 Gb, and so on.

Here are the codes used:

1) Calling JDialog:

private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt)
{
try
{
Database.GetConnection().commit();
}
catch (SQLException ex)
{
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
Log.GetLogger().log(Level.ALL, "jMenuItem1ActionPerformed() Method in MainFrame.Java, Database error!", ex);
MessageBox.ShowMessage(this, ex.toString(), "ERROR", JOptionPane.ERROR_MESSAGE);
}
Insert ins = new Insert(this, true);
ins.setVisible(true);
}


2) Loading values into jTable:

private void LoadTable() throws SQLException
{

Timestamp tstart = new Timestamp(new java.util.Date().getTime());

//get all from database
ResultSet rs;
rs = Database.GetCutiiAll();

Timestamp tstop1 = new Timestamp(new java.util.Date().getTime());

//create a model for the table
int len = Database.GetColoaneArr().length + 1;
javax.swing.table.DefaultTableModel tableModel = new DefaultTableModel(0, len);
//set table headers for columns
String[] headers = new String[Database.GetColoaneArr().length + 1];
headers[0] = "ID";
System.arraycopy(Database.GetColoaneArr(), 0, headers, 1, headers.length - 1);
tableModel.setColumnIdentifiers(headers);
//set selection mode
table1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//insert rows to table
int rowNo = 0;
while (rs.next())
{
//create object array with values for table columns
int length = headers.length;
Object[] data = new Object[length];
for (int i = 0; i < length; i++)
{
//parse values where are foreign keys in the database
Object val = rs.getObject(headers[i]);
switch (headers[i])
{
case "SERIE":
{
String[] temp = Database.GetSerii();
int index = (int) val;

data[i] = temp[index - 1];
break;
}
case "PROTECTIE_EX_1":
case "PROTECTIE_EX_2":
case "PROTECTIE_EX_3":
{
String[] temp = Database.GetProtectii();
int index = (int) val;

data[i] = temp[index - 1];
break;
}
case "TIP_MATERIAL":
{
String[] temp = Database.GetMateriale();
int index = (int) val;

data[i] = temp[index -1];
break;
}
default:
{
data[i] = rs.getObject(headers[i]);
break;
}
}
}
tableModel.insertRow(rowNo, data);
rowNo++;
}
//attach model to table
table1.setModel(tableModel);
//create listeners to update database when changing values
Timestamp tstop2 = new Timestamp(new java.util.Date().getTime());
//show how long it took to load the database
long s = tstop2.getTime() - tstart.getTime();
jDurata.setText(String.valueOf(s) + " ms");
}


3) Disposing JDialog:

private void jBtnIesireActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if (Database.GetCanSave())
{
int answer = MessageBox.ShowConfirmationMessage(this, "Salvati modificarile inainte de a iesi?", "OPTIUNE", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
switch (answer)
{
case JOptionPane.CANCEL_OPTION: break;
case JOptionPane.YES_OPTION: {
try
{
Database.Save();
}
catch (SQLException ex)
{
Logger.getLogger(Insert.class.getName()).log(Level.SEVERE, null, ex);
Log.GetLogger().log(Level.ALL, "Database.Save() Method in Insert.Java, Failed to update database.", ex);
MessageBox.ShowMessage(this, ex.toString(), "ERROR", JOptionPane.ERROR_MESSAGE);
}
break;
}
case JOptionPane.NO_OPTION: {
try
{
Database.RollbackAllSavepoints();
}
catch (SQLException ex)
{
Logger.getLogger(Insert.class.getName()).log(Level.SEVERE, null, ex);
Log.GetLogger().log(Level.ALL, "Database.Undo() Method in Insert.Java, Failed to update database.", ex);
MessageBox.ShowMessage(this, ex.toString(), "ERROR", JOptionPane.ERROR_MESSAGE);
}
finally
{
this.dispose();
}
}
default: break;
}
}
else
this.dispose();
}


Thanks in advance and sorry, I can't format the code here.

Answer Source

It is a very bad idea to load 150000 records into memory. I believe you should have a paging and load only a small chunk into memory at a time, like 10 records. If you switch your strategy to use a paging, then your memory problems will be solved.