2013-02-12 157 views
3

我跟着把一個close()最終塊的做法:java.sql.Connection對象在垃圾回收時會自動關閉嗎?

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

是否真的需要調用連接上close(),或將垃圾收集器會自動做呢?

我確定垃圾收集會帶來額外的延遲,我只是不希望連接永遠保持打開狀態。

+4

它是您的責任,當您完成它的關閉連接。垃圾收集器不會爲你做。 – Perception 2013-02-12 23:01:16

+0

也許這回答你的問題:http://stackoverflow.com/questions/8652336/jdbc-garbage-collection 總結:你需要關閉連接,以防止各種泄漏,不能依靠GC爲你做。 – 2013-02-12 23:01:35

+1

您可能會在連接完成之前耗盡連接。沒有結束就不可靠。你可能喜歡嘗試執行周圍的習語。 (由於你的代碼顯然是編寫的,你似乎會放棄關閉的異常(可能是因爲失敗獲取而導致的NPE) - 您可能想要從那裏拋出某種異常,類似於獲取連接所拋出的異常。對於Java SE 7,您可以使用新的嘗試資源語法來粗略地做正確的事情,但是執行周圍仍然勝利。) – 2013-02-12 23:02:13

回答

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

是的,有必要調用close()。有一些JDBC包裝器可以自動完成這種類型的事情(例如Tomcat連接池),但總的來說,在涉及資源的任何地方都可以清理乾淨。

1

一些JDBC連接實現將在垃圾收集時執行close()。 Postgres JDBC驅動程序的finalize()方法(代碼爲here)就是一個例子。但是,並不能保證情況如此。

但是......

有沒有辦法知道什麼時候該連接對象的垃圾回收將發生。垃圾收集器不瞭解JDBC資源,僅僅關於內存。這意味着GC只能在需要釋放內存時纔會發生。如果你有60個連接,但是仍然有空閒的內存,GC不會運行,你最終將無法連接。

也可能發生某種JDBC連接池。這意味着您獲得的Connection對象不是實際連接,而是包含在池化邏輯中的一個連接。如果你沒有這些連接,池不會知道你已經完成了它們,並且不能夠重用它們用於其他請求,並且連接池將被耗盡。

所以總是close()你的連接明確如果你創建它們。

1

由於數據庫連接不應該保持打開狀態並且Garbage Collecting可能無法關閉它,因此使用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.