当前位置: 首页 > 知识库问答 >
问题:

使用ResultSet从Oracle DB查询时的OutOfMemoryError

全誉
2023-03-14

我的查询返回31,000个结果,每行12列,每行包含大约8,000个字符(每行8KB)。以下是我的处理方式:

public List<MyTableObj> getRecords(Connection con) {
    List<MyTableObj> list = new ArrayList<MyTableObj>();
    String sql = "my query..."; 

    ResultSet rs = null;
    Statement st = null;

    con.setAutoCommit(false);
    st = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    st.setFetchSize(50);
    rs = st.executeQuery(sql);

    try {
        System.out.println("Before MemoryFreeSize = " + (double)Runtime.getRuntime().freeMemory() / 1024 / 1024 + " MB");

        while ( rs.next() ) {
            MyTableObjitem item = new MyTableObj();
            item.setColumn1( rs.getString("column1") );
            ... ...
            item.setColumn12( rs.getString("column12") );

            list.add( item );
        } // end loop

        // try to release some memory, but it's not working at all
        if ( st != null ) st.close();
        if ( rs != null ) rs.close();
        st = null; rs = null;
    }
    catch ( Exception e ) { //do something }
    System.out.println("After MemoryFreeSize = " + (double)Runtime.getRuntime().freeMemory() / 1024 / 1024 + " MB");

    return list;
} // end getRecords

如果每行占用8KB内存,31K应该占用242MB内存。在finish循环查询结果后,我的剩余内存只有142MB,不足以完成其他进程的其余部分。

让我们假设我不能改变数据库的设计,我需要所有的查询结果。处理后如何释放更多内存?

另外:我还尝试不使用resultset.getstring()并使用hardcode字符串重新使用它,在循环之后,我得到了450MB的空闲内存。

我发现,如果我这样做了:

// + counter to make the value different for each row, for testing purpose
item.setColumn1( "Constant String from Column1" + counter );
... ...
item.setColumn12( "Constant String from Column12" + counter );
counter++;
item.setColumn1( rs.getString("column1") );
... ...
item.setColumn12( rs.getString("column12") );

共有1个答案

单淳
2023-03-14

您应该缩小您的查询范围,尽量使其更加具体,如果有必要,在您的查询中添加限制您的java不能处理太大的结果

 类似资料:
  • 问题内容: 我正在对PostgreSQL数据库中的表运行查询。该数据库位于远程计算机上。该表具有约30个使用postgresql 分区功能的子表。 该查询将返回一个很大的结果集,大约有180万行。 在我的代码中,我使用spring jdbc支持,即方法JdbcTemplate.query,但未调用我的RowCallbackHandler。 我最好的猜测是postgresql jdbc驱动程序(我使

  • C:\Users\ramachandran.s oracledb@1.2.0安装C:\Users\ramachandran.s\node\u modules\oracledb node gyp rebuild C:\Users\ramachandran.s\node\u modules\oracledb 我错过了什么,请帮忙

  • 问题内容: 我可以这样创建一个临时表: 但是新表不可读,因为它说它没有主键。 是exisitingtable的主键,因此我希望它在temp表中得到相同的处理。 但是,无论如何,我宁愿找到某种ORM方式来执行此操作。鉴于: 如何在不执行100000命令的情况下填充一些选定的内容?还是有一种方法可以通过类似于上面的普通SQL版本的查询来创建表? 问题答案: 它不完全是ORM,但为了最初创建表,我将克隆

  • 问题内容: 在Java中,我试图从ResultSet中测试是否为空值,在ResultSet中,该列将被转换为原始 int 类型。 从上面的代码片段中,是否有更好的方法可以做到这一点,并且我认为第二个wasNull()测试是多余的? 教育我们,谢谢 问题答案: 默认时,字段值是返回,这也是您的默认值声明。在这种情况下,您的测试是完全多余的。 如果您实际上想在字段值为NULL的情况下执行其他操作,则建

  • node-oracledb 是甲骨文公司官方发布的 Oracle 的 Node.js 驱动。目前最新版本 0.2 还是个预览版本,开发团队还在不断完善,包括对 Windows 平台的支持、LOB 支持、批获取/大查询结果集的流处理以及 DRCP 支持等。 支持 Oracle 的基本和高级特性: SQL 和 PL/SQL 执行 使用 javascript 对象和数组进行绑定 查询结果返回到 Java

  • 我已尝试获取以下代码的结果: 在某些情况下,我需要在上面使用“In cause”。我尝试使用获得结果,但对于param:ref它不能在本机查询中工作,但在ejb ql中,我只是得到了以下错误消息: null 我累坏了,大家能给我一些建议吗?thx寻求帮助