java.sql.Connection对象在收集垃圾时会自动关闭吗?

时间:2013-02-12 22:57:45

标签: java mysql sql garbage-collection

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

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

是否真的有必要在连接上调用close(),还是垃圾收集器会自动执行此操作?

我对垃圾收集引起的额外延迟感到满意,我只是不希望连接永远保持打开状态。

4 个答案:

答案 0 :(得分:5)

  

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

  

或垃圾收集器会自动执行此操作吗?

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

  

我很好,GC会引起额外的延迟。

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

  

我只是不希望连接永远保持开放。

您不希望它们在必要时间内保持打开状态。它们是稀缺资源。不要浪费它们。 "It is recommended that programmers explicitly close all connections (with the method Connection.close) and statements (with the method Statement.close) as soon as they are no longer needed, thereby freeing DBMS resources as early as possible."

答案 1 :(得分: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.

答案 2 :(得分:1)

是的,有必要致电close()。有一些JDBC包装器可以自动执行此类事务(例如Tomcat连接池),但一般来说,在涉及资源的任何地方自行整理是一个非常好的主意。

答案 3 :(得分:1)

当垃圾收集时,某些JDBC连接实现将close()。这方面的一个例子是Postgres JDBC驱动程序的finalize()方法(代码here)。但不能保证是这种情况。

但是...

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

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

如果您创建连接,请始终close()您的连接。