3

我遵循将 aclose()放在最后一个块中的做法:

void foo() {
    Connection conn;
    try {
        conn = getConnection();
        // ..
    } final {
        try {
            conn.close()
        } catch(Exception e) {
        }
    }
}

是否真的需要调用close()连接,或者垃圾收集器会自动执行此操作?

我可以接受垃圾收集会引起的额外延迟,我只是不希望连接永远保持打开状态。

4

4 回答 4

6

真的有必要在连接上调用 Close()

是的。

还是垃圾收集器会自动执行此操作?

未指定。也许一些实现会这样做。你不能依赖它。

我可以接受 GC 会引起的额外延迟。

GC 可能永远不会发生。你真的对无穷大好吗?

我只是不希望连接永远保持打开状态。

您不希望它们保持打开的时间超过必要的时间。它们是稀缺资源。不要浪费它们。“建议程序员在不再需要时立即显式关闭所有连接(使用 Connection.close 方法)和语句(使用 Statement.close 方法),从而尽早释放 DBMS 资源。”

于 2013-02-12T23:17:59.797 回答
2

由于数据库连接不应保持打开状态并且垃圾收集可能不会关闭它,因此使用 Try with Resources 的 Java 7“项目硬币”语法很有帮助。任何实现AutoCloseable的东西都可以使用,如下所示。

void foo() {
   try( Connection conn = getConnection() ) {
      // Do your Database code
   } catch(SQLException e) {
      //Handle the exception
   }
}  //conn is closed now since it implements AutoCloseable.
于 2013-02-13T04:20:01.017 回答
1

一些 JDBC 连接实现会close()在它们被垃圾回收时。一个例子是 Postgres JDBC 驱动程序的 finalize() 方法(此处的代码)。但是,不能保证会出现这种情况。

但...

无法知道连接对象的垃圾收集何时会发生。垃圾收集器不了解 JDBC 资源,只了解内存。这意味着只有在需要释放内存时才会发生 GC。如果您有 60 个连接,但仍有可用内存,则 GC 不会运行,您最终会用完连接。

也有可能发生某种 JDBC 连接池。这意味着Connection您获得的对象不是真正的连接,而是包含在池逻辑中的对象。如果您不使用close()这些连接,池将不会知道您已完成它们并且无法将它们重用于其他请求,并且连接池将被耗尽。

因此close(),如果您创建它们,请始终明确地显示您的连接。

于 2013-02-12T23:20:27.937 回答
1

是的,有必要打电话close()。有一些 JDBC 包装器可以自动执行这种类型的事情(例如 Tomcat 连接池),但总的来说,在涉及资源的地方自行整理是一个非常好的主意。

于 2013-02-12T23:13:11.337 回答