【发布时间】:2014-03-25 23:56:52
【问题描述】:
我正在使用 hsqldb 版本 2.3.1 或 2.3.2(发现两者都有问题)。
我有一些代码,我在其中执行了大量对数据库的插入操作,并且我可能会清理所有资源 - 但我注意到在语句上调用 execute 会导致内存永远不会消失 - 即使我关闭了准备好的语句,连接等......
这是您可以在您的机器上运行并验证的代码(在 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[]。
如果我是对的并且这是一个错误,我正在寻找一种解决方法。有什么建议么?我做错了吗?
谢谢
【问题讨论】:
-
您的回滚尝试不起作用,因为连接处于自动提交模式并且 INSERT 已自动提交。它需要 c.setAutoCommit(false) 在任何插入之前。