Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java springbatch是否在处理每个批之后释放堆内存?_Java_Spring_Spring Boot_Spring Batch - Fatal编程技术网

Java springbatch是否在处理每个批之后释放堆内存?

Java springbatch是否在处理每个批之后释放堆内存?,java,spring,spring-boot,spring-batch,Java,Spring,Spring Boot,Spring Batch,我有一个Spring批处理作业,它只包含一个步骤,使用FlatFileItemReader读取CSV文件(包含大约2000行),并将对象写入数据库。我有自己的自定义BeanWrapperFieldSetMapper,它将行映射到对象。区块大小设置为50,因此我希望在写入每个批处理中的对象(50个对象)后,释放这些对象的堆内存 由于我正在利用批处理,我希望在每个给定的时间只有50个CreditCardDebt对象。但是,在处理最后一批时,我发现堆内存包含2000个CreditCardDebt对象

我有一个Spring批处理作业,它只包含一个步骤,使用
FlatFileItemReader
读取CSV文件(包含大约2000行),并将对象写入数据库。我有自己的自定义
BeanWrapperFieldSetMapper
,它将行映射到对象。区块大小设置为50,因此我希望在写入每个批处理中的对象(50个对象)后,释放这些对象的堆内存

由于我正在利用批处理,我希望在每个给定的时间只有50个CreditCardDebt对象。但是,在处理最后一批时,我发现堆内存包含2000个CreditCardDebt对象

我错过了什么

My BeanRapperFieldSetMapper实现:

@组件(“信用卡债务字段映射测试”)
公共类TestDebtFieldSetMapper扩展了BeanRapperFieldSetMapper{
公共TestDebtFieldSetMapper(){
super.setPrototypeBeanName(“信用卡债务字段映射测试”);
}
@非空
@凌驾
公共信用卡债务映射字段集(字段集字段集){
CreditCardDebt CreditCardDebt=新的CreditCardDebt();
creditCardDebt.setAccount(fieldSet.readString(0));
creditCardDebt.setCardingId(fieldSet.readString(1));
setDueDate(convertToLocalDateViaInstant(fieldSet.readString(2));
creditCardDebt.setDaysPastDue(fieldSet.readInt(3));
creditCardDebt.setOverdueAmount(fieldSet.readDouble(4));
creditCardDebt.setDirectDebitMinimumPayment(fieldSet.readDouble(5));
creditCardDebt.setDirectDebitBalance(fieldSet.readDouble(6));
creditCardDebt.setDirectDebitStatus(fieldSet.readChar(7));
creditCardDebt.setDirectDebitType(DirectDebitType.valueOf(fieldSet.readString(8));
setCreatedDate(LocalDateTime.now());
creditCardDebt.setFileName(“BAL”);
归还信用卡债务;
}
专用LocalDate转换器ToLocalDateViaInstant(字符串dateToConvert){
DateTimeFormatter formatters=模式的DateTimeFormatter.of(“yyyyMMdd”);
返回LocalDate.parse(dateToConvert,格式化程序);
}

这由垃圾收集器处理。与此问题相关的代码部分位于中。在最基本的
ChunkOrientedTasklet形式中,有两个调用:

Chunk<I> inputs = chunkProvider.provide(contribution);
chunkProcessor.process(contribution, inputs);

此过程将重复运行,直到数据源耗尽。因此,当GC启动时,应将已处理块的项进行垃圾收集(因为变量
输入
/
输出
被重复使用)除非在整个作业执行过程中有什么东西将它们保存在内存中。

无论对象是否立即释放,垃圾收集器都将执行实际释放内存的工作。它将决定何时运行,以及保留什么内容与实际释放什么内容-取决于运行时的环境,有时决定是o保留垃圾。问题是,如果我使用更大的输入(140k行)测试作业我将块大小设置为1000,将堆内存大小限制为64MB,以便强制GC采取行动,在处理前3个批处理后,我得到一个
java.lang.OutOfMemoryError:GC开销限制已超出。
看起来,在使用该批处理完作业后,属于该批的实例不会被清理。这是预期行为?已处理块的项应进行垃圾收集(我添加了一个包含更多详细信息的答案)。您确定您的自定义
BeanwrapPerfiedSetMapper
(或其他内容)吗在整个作业执行过程中不保留项?我已在问题描述中添加了我的BeanwrapPerfiedSetMapper的实现。您好,我也有同样的问题,您是否找到了此问题的答案?
Chunk<O> outputs = transform(contribution, inputs);
write(contribution, inputs); // details of adjustments of output omitted here