java 资源耗尽事件:JVM无法从堆中分配内存

z9smfwbn  于 2022-10-30  发布在  Java
关注(0)|答案(1)|浏览(192)

我尝试在微服务中提取超过100万条记录。我遇到错误。我需要不断增加服务的应用内存,以便提取大量数据。有没有什么方法可以用来提取大量数据,而不是增加应用内存。
[错误]资源耗尽事件:JVM无法从堆中分配内存。2022- 1/0 - 11 T11:22:04. 898 +08:00 [APP/PROC/WEB/0] [ERR]资源已耗尽!(1/0)

@Value("${batch-size}")
        private int batchSize;

    public void archiveTableRecords(JdbcTemplate sourceDbTemplate, JdbcTemplate targetDbTemplate,
        ArchiveConfigDTO archiveObj) {
            try {
                String sourceTable = archiveObj.getSourceTable();
                String archive_months =archiveObj.getArchiveCriteriaMonths();
                List<Object> primaryKeyValueList = new ArrayList<>();
                String compareDate1 = getCSTDateNew(archive_months);
                logger.info("Archive criteria date: {}", compareDate1);
                List<Map<String, Object>> sourceRecords = sourceDbTemplate
                        .queryForList(ArchiveSQLQueries.buildSQLQueryToFetchSourceRecords(sourceTable), compareDate1);
                int sourceRecordsSize = sourceRecords.size();
                logger.info("Fetched {} {} record(s)", sourceRecords.size(), sourceTable);
                if (sourceRecordsSize > 0) {
                    int recordsInserted = copySourceRecords(targetDbTemplate, archiveObj.getTargetTable(),
                            archiveObj.getPrimaryKeyColumn(), sourceRecords, primaryKeyValueList);
                    if (recordsInserted > 0)
                        deleteSourceRecords(sourceDbTemplate, sourceTable, archiveObj.getPrimaryKeyColumn(),
                                primaryKeyValueList);
                }
            } catch (Exception e) {
                logger.error("Exception in archiveTableRecords: {} {}", e.getMessage(), e);
            }
        }

    public static String buildSQLQueryToFetchSourceRecords(String sourceTable) {
            StringBuilder sb = new StringBuilder("SELECT * FROM " + sourceTable + " where update_dts <= ?");
            return sb.toString();
        }

        public int copySourceRecords(JdbcTemplate targetDbTemplate, String targetTable, String primaryKeyColumn,
                List<Map<String, Object>> sourceRecords, List<Object> primaryKeyValueList) {
            int result = 0;
            logger.info("Copying records to {}", targetTable);
            int[][] insertResult = targetDbTemplate.batchUpdate(
                    ArchiveSQLQueries.buildSQLTargetRecordInsertionQuery(targetTable, sourceRecords.get(0),
                            primaryKeyColumn),
                    sourceRecords, batchSize, new ParameterizedPreparedStatementSetter<Map<String, Object>>() {
                        @Override
                        public void setValues(PreparedStatement ps, Map<String, Object> argument) throws SQLException {
                            int index = 1;

                            for (Entry<String, Object> obj : argument.entrySet()) {
                                if (obj.getKey().equals(primaryKeyColumn))
                                    primaryKeyValueList.add(obj.getValue());
                                else
                                    ps.setObject(index++, obj.getValue());
                            }
                        }
                    });

            result = getSumOfArray(insertResult);
            logger.info("Inserted {} record(s) in {}", result, targetTable);
            return result;
        }

I have tried above code when fetching the data somehow i’m getting error .
vohkndzv

vohkndzv1#

根据方法名称判断,您可以从一个表复制到另一个表。使用LIMITOFFSET分批执行此操作。简化示例:

SELECT *
FROM table
WHERE condition
ORDER BY column_which_ensures_last_added_data_is_fetched_last
LIMIT 5
OFFSET 0;

对于下一批,使用已处理记录的数量更改偏移量。更多示例请参考documentationORDER BY一列,这样您可以先获取最旧的数据,最新的数据在最后,以确保不会获取重复的数据。如果主键是自动递增的id,则这是实现此目的的好选择。
如果您需要计数用于记录目的,请使用COUNT函数,或使用批次计数计算已行程实体的数目。

SELECT COUNT(*)
FROM table
WHERE condition;

相关问题