【发布时间】:2011-09-19 19:56:01
【问题描述】:
我正在使用 java.sql PreparedStatements,我想知道以下问题:
在Java is Pass-by-Value, Dammit! 中,给出了以下作为 Java 的 Pass-By 约定的示例:
public void foo(Dog d) {
d = new Dog("Fifi"); // creating the "Fifi" dog
}
Dog aDog = new Dog("Max"); // creating the "Max" dog
// at this point, aDog points to the "Max" dog
foo(aDog);
// aDog still points to the "Max" dog
在我的代码中,这出现如下(半 Java 伪代码):
public void method() {
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
rs = executeStatement(sql-string, pstmt, conn, vars...);
} catch (....) { /* error-handling */ }
/// do stuff with the data
rs.close();
}
executeStatement 是(类似于)以下内容:
ResultSet executeStatement(String sql, PreparedStatement pstmt, Connection conn, Object[] vars...) {
pstmt = conn.prepareStatement(sql);
/// set pstmt variables...
ResultSet rs = pstmt.execute();
return rs;
}
根据我对 Java 的传递约定的理解,我在主代码中使用 pstmt 做任何事情都没有用,因为即使在调用 executeStatement 之后它仍然是 null。但是,因为关闭 PreparedStatement 也会关闭 ResultSet,所以我知道在处理 ResultSet 时在 executeStatement 中创建的 PreparedStatement 不会关闭。
这是否意味着这里存在内存泄漏? (我对内存泄漏以及如何诊断/修复它们的理解充其量是参差不齐的)。有什么方法可以让我以不同的方式构造它以避免泄漏,但继续使用可以执行 SQL 字符串并以抽象方式返回 ResultSet 的方法?
【问题讨论】:
-
在上面的代码中, psmt 以 null 开始,但如果 conn.prepareStatemenet(...) 返回不为 null 的内容,则在方法完成后,全局变量 psmt 将不为 null。但是,在连接对象上调用 close(),与创建 PreparedStatement 和 ResultSet 相同的对象也会关闭这些对象,所以你应该没问题,没有 JDBC 资源仍然是垃圾不可回收...
-
哦,太好了!我忘记了关闭连接会释放这些资源。谢谢!
-
只是为了回答按值传递/按引用传递的问题:是的,您的
executeStatement方法的pstmt参数在当前形式中根本没有任何功能,因为它的 @987654332 @值在方法的第一个赋值中被覆盖。
标签: java sql jdbc memory-leaks prepared-statement