Hsqldb - 内存过度使用?

时间:2014-03-27 06:09:33

标签: java hsqldb h2

我在服务器内存模式下使用hsqldb 2.3.2。 我遇到的情况是我向hsqldb插入一些信息,并且HSQLDB使用的堆空间(即使在GC之后)比我在Java堆中的普通HashMap / LinkedList中保存的大3到4个。

以下是将多条记录插入内存中的hsqldb服务器的代码:

    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跟踪服务器HSQLDB进程 我运行上面的代码,直到出现OutOfMemory

我尝试了不同的堆大小&amp;我停止了上面的代码 - 令人不安的是我总是看到我已插入大约13,800,000行 - 在服务器中有3GB可用堆 - 并且在终止上面的代码并且执行GC 0之后堆已满,堆需要2500MB -

这意味着每行占用大约180个字节 - 一个长的占用8个字节 - 因此这个重22倍。

这当然只是一个测试,真正的表通常只有一个字段 - 但我探讨的原因是当我尝试将1GB内存从oracle复制到HSQLDB时 - 在HSQLDB中它最终保持4GB ! (表结构相同)

现在,问题:

  1. 发生了什么事?我的测试看起来是否正确?

  2. 如何减少HSQLDB中的内存消耗?

  3. 如果没有简单的方法,其他类似的产品可能有合理的内存使用量?在这种情况下,H2怎么样?

  4. 谢谢

2 个答案:

答案 0 :(得分:0)

最后我选择了H2,它占据了原始尺寸的1.2左右(在我的情况下)。它还具有额外的内存压缩模式。

答案 1 :(得分:-1)

这不是关系数据库的正确用例。您有一个只有一列的表,并存储一些长(BIGINT)值。您甚至没有主键,以便您搜索已插入的值。

这种用法甚至不需要HashMap。只需使用任何库中的HashSet实现。