Я испытываю утечку памяти с кодом, подобным приведенному ниже (это симуляция с разными входами в каждом цикле).
Проблема
Объект Object_XXX довольно сложный, с подключениями к базам данных и другими объектами, заполненными данными из баз данных, а также.
for(int i=0; i<MAX; i=i+1){
Class_XXX Object_XXX = new Class_XXX(Arg_1, Arg_2);
// action with Object_XXX
}
Теперь, после вызова нескольких методов, Object_XXX также можно отбросить, поскольку для следующего цикла потребуется объект с другими характеристиками (разные массивы, размер массивов, вложенные объекты ...).
Конструктор аналогичен приведенному ниже, а другие классы имеют аналогичный конструктор.
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());
}
}
Вопросы
Какой подход был бы наиболее правильным в этом случае?
а) завершить Object_XXX в конце цикла
б) чтобы завершить каждый отдельный объект, который составляет Object_XXX, когда они не используются внутри кода?
Лично я предпочел бы а), поскольку я думаю, это позволит сборщику мусора работать без особых проблем с ним
Не могли бы вы также привести пример кода или ссылку?
Спасибо!
Второй раунд:
После ответов, найденных ниже, и просмотра этой другой страницы (http://accu.org/index.php/journals/236),, это шаблон, который я сейчас использую для конструкторов. Слишком рано, чтобы увидеть, работает ли он. По-прежнему есть " exception.toString", но реальный код присваивает переменным стандартные значения в случае исключения и сообщает о действии в журнале.
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
}