2013-11-22 47 views
0

我試圖通過關閉它並在finally塊中將值設置爲null來釋放JDBCResultSet所使用的空間。例如:爲什麼JDBC ResultSet沒有被垃圾收集

try{ 
    //some query executed here and resultset used to get the values from the db 
}catch(Exception exp){ 
//log exception here 
}finally{ 
//close resultset 
    if(rs != null){ 
    rs.close(); 
    rs = null; 
} 
} 

當我檢查打開的ResultSet的YourKit數量,即使所有的結果集被關閉,並設置爲空,而不是顯示0結果集開放YourKit正顯示出打開的ResultSets一些非零值。任何人都可以請幫助我在這裏使結果集數量爲0.

在此先感謝。 Tanmayee

+0

IIRC,只要它保持打開狀態,連接可以保持它創建的結果集。我遇到過這種研究多線程應用程序中內存泄漏的行爲。查看是否在關閉連接時收集結果。 – 0xCAFEBABE

回答

0

close可能會引發這可能導致開放ResultSet(罕見的,但可能的情況)的錯誤,最好DB資源的清洗應該在try-catch發生:

finally { 
if(rs != null) { 
try{ 
rs.close(); 
}catch(Exception e) { 
//handle, log .. 
} 
} 

有了這個ATLEAST您可以瀏覽日誌close故障,並與YourKit同步!

+0

謝謝你的建議苛刻。我將在代碼中添加這些以避免在關閉ResultSet時拋出的異常。 – tanmayees

1

java中的垃圾收集與C不同,您可以在其中釋放內存,並立即釋放內存。在Java中,其運行垃圾回收器的時間可能會超過JVM,但某些可能的情況可能會超出內存JVM調用垃圾回收器的條件,一個是我們調用System.gc()方法的情況,但調用此方法不會導致調用垃圾回收器。 在上述情況下,您正在使對象符合垃圾回收的條件,您不會從內存中釋放任何內容。

+1

澄清Aayush的聲明......當您調用'System.gc()'時,您正在發出JVM的*請求*來收集垃圾,而不是需求。 JVM可能會或可能不會在請求時收集垃圾。所以你的ResultSet對象可能會留在內存中作爲垃圾回收的候選對象。請參閱[doc](http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#gc())。 –

+0

謝謝Aayush和Basil的快速回復。那麼你是說即使在YourKit中顯示的ResultSet的計數不是0,它可能不是內存泄漏的情況嗎? – tanmayees

+0

如果您已經理解了答案,請將問題標記爲已讀。 –

0

在finally塊中你可以這樣寫,那麼它會工作,因爲,這裏爲什麼我們使用try-catch塊意味着有時ResultSet對象可能可用或不可用。

finally{ 
try{ 
if(rs!=null){ 
rs.close(); 

    }}catch(Exception e){ 
e.printStackTrace(); 
} 
} 
+0

謝謝你的建議。我將在代碼中添加這個。 – tanmayees

1

作爲YourKit開發商,我建議重現的情況時,結果集是在內存(當他們不應該)和捕捉內存快照。

之後,您將能夠找到從ResultSet到垃圾收集器根的路徑。這將是ResultSets泄露的原因。這裏有一個鏈接來幫助如何使用GC路徑http://www.yourkit.com/docs/java/help/paths.jsp