我有内存泄漏问题。我的代码的示意图:
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
答案 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();