如果不关闭 JDBCPreparedStatements,是否会导致内存泄漏?

Ben*_*ole 5 java sql memory-leaks jdbc prepared-statement

我正在使用 java.sqlPreparedStatements,我想知道以下内容:

Java 中是按值传递,该死!,下面给出了 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 
Run Code Online (Sandbox Code Playgroud)

在我的代码中,如下所示(半 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();
}
Run Code Online (Sandbox Code Playgroud)

其中executeStatement(类似于)以下内容:

ResultSet executeStatement(String sql, PreparedStatement pstmt, Connection conn, Object[] vars...) {
  pstmt = conn.prepareStatement(sql);
  /// set pstmt variables...
  ResultSet rs = pstmt.execute();
  return rs;
}
Run Code Online (Sandbox Code Playgroud)

根据我对Java传递约定的理解,我在主代码中对 pstmt 做任何事情都是没有用的,因为即使在调用executeStatement. 但是,因为关闭 aPreparedStatement也会关闭 ResultSet,所以我知道在处理 ResultSet 时,PreparedStatement创建的 并没有关闭。executeStatement

这是否意味着这里存在内存泄漏?(我对内存泄漏以及如何诊断/修复它们的理解充其量是参差不齐的)。有什么方法可以以不同的方式构造它以避免泄漏,但继续使用可以执行 SQL 字符串并以抽象方式返回 ResultSet 的方法?

Coo*_*ans 2

我在这里没有看到内存泄漏。我发现的唯一问题是您没有在finally 块中关闭结果集。因此,如果抛出异常,则rs.close()不会执行。

正如 Andrei 评论的那样,关闭结果集也会关闭底层语句。我不确定你在哪里关闭连接,但这也应该发生在finally块中。

  • @BenCole - 你不应该对在finally 块中关闭持怀疑态度。这是关闭资源的标准和推荐方式。 (2认同)