Java 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

我正在服务器内存模式下使用HSQLDB2.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和 我一直运行上面的代码,直到发生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。而且它在内存模式中也有额外的压缩。