2013-02-15 59 views
2

我有內存泄漏問題。我的代碼這schemat:ResultSet在關閉後需要RAM

CallableStatement c = Baza.conn.prepareCall("select * from something");   
ResultSet rs = c.executeQuery();//takes about 100sec 

while(rs.next()) 
{ 
//do stuff, only calculations, I don't create any object 
} 

rs.close(); 
c.close(); 

雖然executeQuery正在執行RAM的使用上升到300MB,並永遠不會再下降。當程序再次在同一個地方(但有輕微的不同選擇),有時候Ram的使用會再次上升,有時不會。舒爾德給我的東西不僅僅是近在咫尺ResultSet?幫助將非常感激,因爲現在我必須每隔幾個小時重新啓動一次該程序。

我使用JDBC4和posgresql

+2

究竟是你測量和什麼操作系統?即使Oracle不再需要它,Oracle JVM也會保留從操作系統分配的內存。 – radai 2013-02-15 18:12:15

+0

在查詢中使用分頁 – 2013-02-15 18:12:27

+0

我正在測量Windows任務管理器中的RAM使用情況。 – user2076513 2013-02-15 18:15:27

回答

0

請務必關閉 「conn將」 過。

JVM在內部管理內存。您不一定期望您的操作系統報告的RAM利用率立即被釋放。它最終應該在JVM執行垃圾收集時發佈。配置一個JMX偵聽器並使用JConsole監視JVM內存,不要相信操作系統。

0

如果查詢需要那麼長時間,可能是連接速度很慢,或者你收回大量數據。將所有數據保存在RAM中並不是最佳解決方案。正如Jigar Joshi的評論已經指出的那樣:你可能想看看分頁。此外,關閉連接也是一種很好的做法。關於垃圾收集考慮Java7,它有一個新的垃圾收集器(例如見Java 7 (JDK 7) garbage collection and documentation on G1),可能更適合您的需求

1

您可以使用遊標並設置獲取大小以減少查詢的內存使用量。

Baza.conn.setAutoCommit(false); // Turn off autocommit on the connection to enable cursors in JDBC 
CallableStatement c = Baza.conn.prepareCall("select * from something");   
c.setFetchSize(1000); // The fetch size determines the number of records returned in each "Batch" 
ResultSet rs = c.executeQuery();// This may appear to run faster depending on the query 

// Nothing changes here. The JDBC driver handles the cursor for you. 
while(rs.next()) 
{ 
//do stuff, only calculations, I don't create any object 
} 

rs.close(); // This will close the cursor 
c.close(); // I would recommend re-enabling autocommit if you weren't closing the connection here 
0

你可以使用:

Baza.conn.setAutoCommit(false); 

之前,ResultSet,並使用:

rs.getMoreResults(java.sql.Statement.CLOSE_CURRENT_RESULT); 
Baza.conn.commit(); 

的ResultSet之後和之前

rs.close(); 
c.close();