ResultSet在关闭后占用RAM

时间:2013-02-15 18:09:56

标签: java postgresql jdbc 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

4 个答案:

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

答案 1 :(得分:0)

确保关闭“conn”。

JVM在内部管理内存。您不一定要求立即释放操作系统报告的RAM利用率。当JVM执行垃圾收集时,它最终应该被释放。配置JMX侦听器并使用JConsole监视JVM内存,并且不信任操作系统。

答案 2 :(得分:0)

如果查询花了那么长时间,可能是连接速度很慢,或者你得到大量数据。将所有数据保存在RAM中并不是最佳解决方案。正如Jigar Joshi的评论已经指出:你可能想看看分页。此外,关闭连接也是一种很好的做法。关于垃圾收集考虑Java7,它有一个新的垃圾收集器(例如见Java 7 (JDK 7) garbage collection and documentation on G1),可能更适合您的需求

答案 3 :(得分:0)

你可以使用:

Baza.conn.setAutoCommit(false);
在ResultSet之前

,并使用:

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

在ResultSet之后和

之前
rs.close();
c.close();