【发布时间】:2011-04-17 17:43:01
【问题描述】:
我遇到了内存泄漏,代码类似于下面的代码(这是一个在每个循环中都有不同输入的模拟)。
问题
对象 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());
}
}
问题
在这种情况下,最正确的方法是什么? a) 在循环结束时完成 Object_XXX b) 在代码中不使用组成 Object_XXX 的每个对象时,最终确定它们吗? 就我个人而言,我更喜欢 a) 因为 我认为 这会让垃圾收集器继续工作而不会造成太多麻烦
能否提供代码示例或参考资料?
谢谢!
第二轮:
在找到下面的答案并查看另一个页面 (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
}
【问题讨论】:
-
这取决于您使用的 SQL API...如果结果集有某种关闭方法,您绝对应该在某个时候调用它。
-
(您可能想尝试 Execute Around 习语来摆脱一些通用代码(尽管直到[/if] 我们得到 lamdas/简洁的匿名内部类,它仍然很冗长)。)跨度>
标签: java constructor garbage-collection destructor