Hsqldb—一个可能的准备语句内存泄漏



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

我有代码,其中我执行了很多插入到数据库,我清理所有的资源,我可能-但我已经注意到,调用执行语句,导致内存永远不会消失-即使,我关闭准备语句,连接等…

下面是你可以在你的机器上运行并验证的代码(在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[].

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

谢谢

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

如果没有指定,即使关闭最后一个连接到内存数据库中的HSQL,数据库本身也不会被销毁,而是保留在内存中。

每插入一行,数据库就会增长。

如果数据库不留下,那么你永远不能插入,因为在你创建了数据库和表t之后,你关闭了连接,然后在重新打开后,表应该消失了,不是吗?

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

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

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

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

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

如果你正在处理更大的数据,你的第一个选择应该是在文件系统中创建一个基于磁盘的缓存表的HSQL数据库。那么它的内存占用就不会像在内存中那样随着数据的增长而增长。

最新更新