【问题标题】:OutOfMemoryError: Java heap space , while retrieving data by using Jdbctemplate : (RowCallbackHandlerResultSetExtractor.extractData)OutOfMemoryError: Java heap space ,同时使用 Jdbctemplate 检索数据:(RowCallbackHandlerResultSetExtractor.extractData)
【发布时间】:2020-09-17 10:16:56
【问题描述】:
public List<Employee> getEmployeeDataByDate(Date dateCreated) throws Exception {
        List<Employee> listDetails = new ArrayList<>();
        
        sqlServTemplate.query(SyncQueryConstants.RETRIEVE_EMPLOYEE_RECORDS_BY_DATE, new Object[] { dateCreated },
                new RowCallbackHandler() {

                    @Override
                    public void processRow(ResultSet rs) throws SQLException {
                        Employee emp = new Employee();
                        emp.setEmployeeID(rs.getString("employeeID"));
                        emp.setFirstName(rs.getString("firstName"));
                        emp.setLastName(rs.getString("lastName"));
                        emp.setMiddleName(rs.getString("middleName"));
                        emp.setNickName(rs.getString("nickName"));

                        byte[] res = rs.getBytes("employeeImage");
                        Blob blob = new SerialBlob(res);
                        emp.setEmployeeImage(blob);

                        
                        // .....
                        
                        listDetails.add(emp);
                    }
                    
        });
        
        return listDetails;
    }

这里我正在尝试检索员工表的记录。因为 BLOB 数据它说 OutOfMemoryError: Java heap space 。有人可以帮我吗?

这是一个独立的应用程序,我正在从一个表同步到另一个表。所以无法使用分页。每天 2k 记录将通过 cron 作业在午夜同步。给出一些想法,我可以如何解决这个问题。

SELECT * FROM Employees with(nolock) WHERE cast (datediff (day, 0, dateCreated) as datetime) >= ?

这个查询给了我所有基于日期的数据,(每天大约 2k 条记录)。 如果我在评论

byte[] res = rs.getBytes("employeeImage");
                        Blob blob = new SerialBlob(res);
                        emp.setEmployeeImage(blob);

这一行就没有问题了。否则会抛出错误。

请给出一些想法,如果可能的话,给出一些示例代码。 我在这个位置上挣扎了 2 天。

【问题讨论】:

  • 问题是什么?太多数据无法放入可用堆空间。
  • 增加你的堆,或者你可以简单地使用分页,每个查询得到 100 条记录
  • 我有另一个有 40 万条记录的表,没有问题。(我也没有使用任何分页)只有在这个有问题的表中。
  • 只有我发现的不同之处在于每条记录有 120 个字段,那里只有 50 个字段。
  • BLOB/CLOB 字段?我的猜测:兆字节大小的肖像照片。不使用所有字段进行测试。

标签: java spring spring-mvc spring-data-jpa jdbctemplate


【解决方案1】:

正如其他一些评论者所提到的,您可以增加堆空间或限制从查询返回的记录数量,并以较小的批次处理它们。

【讨论】:

    【解决方案2】:

    您正在读取以字节为单位的 MB 大小的图像,它将消耗您的 HEAP 内存。 而是尝试使用 BinaryStream:

    InputStream image = rs.getBinaryStream("employeeImage");
    

    【讨论】:

      【解决方案3】:

      而不是将每个用户添加到列表中,您可以一次处理一个。将每条记录从源数据库中提取到另一个数据库中,而不是将它们添加到导致 OOM 错误的列表中。如果下游还有其他处理,则将一个类注入到此 DAO 中,以处理实际处理/写入目标数据库。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-22
        • 1970-01-01
        • 2020-11-16
        • 2017-03-28
        相关资源
        最近更新 更多