Hi!
I am experiencing a memory leak with a code similar to the one below (it's a simulation with different inputs at every loop).
The problem
The object Object_XXX is quite complex, with connections to databases and other objects populated with data from databases aswell.
for(int i=0; i<MAX; i=i+1){
Class_XXX Object_XXX = new Class_XXX(Arg_1, Arg_2);
// action with Object_XXX
}
Now, after calling a couple of methods, Object_XXX can also be discarded since the next loop will requires an object with different characteristics (different arrays, size of the arrays, nested objects...).
The constructor is similar to the one below, and the other classes have a similar constructor.
public Class_XXX(Arg_1, Arg_2, DB_Connection){
try {
Statement Query_Statement = null;
ResultSet Query_ResultSet = null;
String Query_String = null;
Query_String = "...";
Query_Statement = DB_Connection.createStatement();
Query_ResultSet = Query_Statement.executeQuery(SQL);
while (Query_ResultSet .next()) {
this.Param_1 = Query_ResultSet .getString("param_1");
this.Param_2 = Query_ResultSet .getString("param_2");
...
this.Param_n = Query_ResultSet .getString("param_n");
}
} catch (SQLException e) {
System.out.println("SQL Exception: "+ e.toString());
}
}
Questions
What would be the most correct approach in this case? a) to finalize Object_XXX at the end of the loop b) to finalize every single object that compose Object_XXX when they are not used inside the code? Personally I would prefer a) since I think this would leave the garbage collector to work without messing too much with it
Could you also provide a code example or a reference?
Thanks!
Second round:
After the answers found below and a look at this other page (http://accu.org/index.php/journals/236), this is the template that i'm using now for the constructors. Too early to see if it works. There is still the "exception.toString" but the real code gives to the variables standard values in the case of an exception and reports the action in a log.
public Class_XXX(String Object_Name, java.sql.Connection Query_Connection){
try{ // begin try-catch for Query_Connection
Statement Query_Statement = Query_Connection.createStatement();
try { // begin try-finally for Query_Statement
String Query_String = "SELECT param_1, param_2, ... param_3 FROM table_name WHERE object_name = '" + Object_Name + "'";
ResultSet Query_ResultSet = Query_Statement.executeQuery(Query_String);
try { // begin try-finally for Query_ResultSet
while (Query_ResultSet.next()) {
this.Param_1 = Query_ResultSet.getString("param_1");
this.Param_2 = Query_ResultSet.getString("param_2");
// ...
this.Param_n = Query_ResultSet.getString("param_n");
}
} finally {
try { Query_ResultSet.close(); }
catch (SQLException ex) { System.out.println("Error in Class_XXX constructor - " + ex.toString()); }
} // end try-finally for Query_ResultSet
} finally {
try { Query_Statement.close(); }
catch (SQLException ex) { System.out.println("Error in Class_XXX constructor - " + ex.toString()); }
} // end try finally for Query_Statement
} catch(SQLException ex) {
System.out.println("Error in Class_XXX constructor - " + ex.toString());
} // end try-catch for Query_Connection
}