Hsqldb - 可能的准备语句内存泄漏

时间:2014-03-25 23:56:52

标签: java jdbc hsqldb

我使用的是hsqldb版本2.3.1或2.3.2(两者都有问题)。

我有代码,我在其中对数据库执行了大量插入操作,并且我清理了所有可能的资源 - 但是我注意到调用execute on语句会导致内存永远不会消失 - 尽管如此,我关闭准备好的声明,连接等......

以下是您可以在您的计算机上运行并验证的代码(在java默认堆大小上运行它,OutOfMemory应该在不到5分钟内出现):

Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:a");
PreparedStatement ps = c.prepareStatement("set database sql syntax ora true");
ps.execute();
ps.close();

ps = c.prepareStatement("create table t (x varchar2(1000 char))");
ps.execute();
ps.close();
c.close();
String str = "abcdefghijklmnopqrstuvwxyz";
str = str + str + str + str + str; //just a long string to rapid the outcome
String x = String.format("insert into t values('%s')",str);
for(int i=0;i<1000*1000*1000;i++){
   c = DriverManager.getConnection("jdbc:hsqldb:mem:a");
   ps = c.prepareStatement(x);
   ps.executeUpdate(); //if I remove this line, there is no memory leak
   ps.clearParameters();//I really try to clean every possible thing
   ps.clearWarnings();//really try
   ps.cancel();//cancel it even
   ps.close();//close it of course
   ps = null;//nullify to hint the GC
   c.rollback(); //Rollback so that memory isn't even used inside the hsqldb
   c.close();//close the connection even

   if(i%100000 == 0){//Every once in a while a report about heap condition
 System.gc();//perform gc
     System.out.println(Runtime.getRuntime().freeMemory()/1024/1024);//in MB
   }
 }

如果您运行代码,定期打印将打印可用的可用内存 - 这将逐渐减少直到OutOfMemory。

正如你所看到的,我尝试过关闭,回滚,无效等等 - 似乎没什么用。

使用JvisualVM,大多数内存都是byte []。

如果我是对的并且这是一个错误,我正在寻找一种解决方法。有什么建议?我做错了吗?

谢谢

1 个答案:

答案 0 :(得分:3)

请在此处阅读http://hsqldb.org/doc/guide/dbproperties-chapt.html关于关机的信息。

如果未指定,即使您关闭内存数据库中HSQL的最后一个连接,数据库本身也不会被破坏并保留在内存中。您正在添加此数据库中的每个插入新行,并且它会增长。

如果数据库不能保留,那么你永远不能插入,因为在你创建数据库和表t之后你关闭了连接,然后在重新打开之后,表就应该消失了,不管它。 / p>

如果您是第一次打开它,可以在最后一次连接关闭后强制关闭数据库:

Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:a;shutdown=true");

但是现在你不能再插入了,因为在新getConnection之后你的桌子不存在。

关闭数据库并释放所有内存的另一种可能性是HSQL的SQL命令SHUTDOWN

c.createStatement().execute("SHUTDOWN");

如果您正在处理更大的数据,您的第一个选择应该是在文件系统中使用基于光盘的CACHED表创建HSQL数据库。然后它的内存占用量不会随着内存中的数据而增长。