Java Hsqldb-内存过度使用?
我正在服务器内存模式下使用HSQLDB2.3.2。 我遇到了这样一种情况:我向hsqldb插入了一些信息,即使hsqldb在GC之后使用的堆空间也比我将其保存在java堆中的普通HashMap/LinkedList中要大3到4 下面是将多条记录插入内存中hsqldb服务器的代码:Java Hsqldb-内存过度使用?,java,hsqldb,h2,Java,Hsqldb,H2,我正在服务器内存模式下使用HSQLDB2.3.2。 我遇到了这样一种情况:我向hsqldb插入了一些信息,即使hsqldb在GC之后使用的堆空间也比我将其保存在java堆中的普通HashMap/LinkedList中要大3到4 下面是将多条记录插入内存中hsqldb服务器的代码: Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost","sa",""); c.setAutoCommit(f
Connection c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost","sa","");
c.setAutoCommit(false);
PreparedStatement ps = c.prepareStatement("set database sql syntax ora true");
ps.execute();
ps.close();
ps = c.prepareStatement("create table t (x long)");
ps.execute();
ps.close();
c.close();
String x = "insert into t values(?)";
c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost","sa","");
c.setAutoCommit(false);
ps = c.prepareStatement(x);
for(int i=0;i<1000*1000*10000;i++){
long z = new Random().nextLong();
ps.setLong(1, z);
ps.addBatch();
if(i%1000==0){
ps.executeBatch();
ps.clearParameters();
ps.clearBatch();
ps.close();
ps = null;
ps = c.prepareStatement(x);
}
c.commit();
c.close();
if(i%100000 == 0){
System.out.println(i);//print number of rows inserted
c.commit();
c.close();
c = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost","sa","");
c.setAutoCommit(false);
ps = c.prepareStatement(x);
}
}
我使用JVisutalVM和
我一直运行上面的代码,直到发生OutOfMemory
我尝试了不同的堆大小&我停止了上面的代码-令人不安的是,我总是看到我在具有3GB可用堆的服务器中插入了大约1380000行-在终止上面的代码并执行GC 0后,堆已满。堆占用2500MB-
这意味着每一行占用大约180个字节,一个长的行占用8个字节,所以这是重的22倍
这当然只是一个测试,真正的表通常不会只有一个字段——但我研究这个问题的原因是,当我尝试将1GB内存从oracle复制到HSQLDB时,HSQLDB中的内存最终会达到4GB!表结构相同
现在,问题是:
发生了什么事?我的测试似乎正确吗
如何减少HSQLDB中的内存消耗
如果没有简单的方法,还有哪些类似的产品可以合理地使用内存?H2在这种情况下是怎样的
谢谢对于关系数据库来说,这不是一个合适的用例。您有一个只有一列的表,并且正在存储一些长BIGINT值。您甚至没有主键来搜索插入的值
这种用法甚至不需要HashMap。只需使用任何库中的HashSet实现。最后,我选择了H2,它占据了我案例中原始大小的1.2。而且它在内存模式下也有额外的压缩。就像我写的那样-我有一个实际的案例,有真正的索引表-它需要4到5倍的时间。长字段示例只是证明。最后,我选择了H2,它占据了我案例中原始大小的1.2。而且它在内存模式中也有额外的压缩。