我正在使用具有多个步骤的spring batch,随着执行的进行,我发现内存占用量正在增长,因为我正在使用Map结构存储从多个csv文件读取的数据。我正在使用这些数据来做一些转换记录。
所以我的问题是释放内存的最正确方法是什么。
@Bean
public Job importParameterJob() {
return jobBuilderFactory.get("importParameterJob")
.incrementer(new RunIdIncrementer())
.start((step1()))
.next((step2))
.next((step3))
.next((step4))
.next((step5))
.next(finalStep())
.build();
}
让我们在这里举个例子,我的第2步使用列表将csv文件中的alla reds记录存储到Map(列表),更准确地说,第2步的Item处理器将所有记录存储在Map List上
public class Step2ItemProcessor implements ItemProcessor<Step2FileRow, Step2FileRow> {
private static final Logger log = LoggerFactory.getLogger(Step2ItemProcessor.class);
private Map<Long , Step2FileRow> step2FileRowMap;
public Step2ItemProcessor() {
step2FileRowMap = new HashMap<Long , Step2FileRow>();
log.info("Step2 ItemProcessor a été crée avec une Map pour charger tous les Step2s");
}
@Override
public Step2FileRow process(final Step2FileRow Step2FileRow) throws Exception {
step2FileRowMap.put(Step2FileRow.getId(), Step2FileRow);
log.info("Le Step2 ID :" + Step2FileRow.getId() +" a été ajouté dans la liste des Step2s en memoire Map");
return null;
}
public Map<Long , Step2FileRow> getstep2FileRowMap() {
return step2FileRowMap;
}
}
由于某些原因,我需要在其他步骤中使用此地图,
因此,如果所需的列表用于执行我必须执行的操作,则所有这些记录在工作完成后仍在内存中,我的问题是我可以用他的列表释放此ItemProcessor。
我应该使用taklet并注入此ItemProcessor,然后将其列表设置为null吗?或使用clear()方法从Map中释放记录
@Autowired
private Step2ItemProcessor listObject;
最佳答案
您要执行的操作有两种选择:
将组件定义为步骤作用域-这将允许每个步骤获得其自己的实例,并且先前的实例可用于垃圾回收。
在组件上实现ItemStream
接口-ItemStream
接口旨在由任何有状态的Spring Batch组件实现。它提供了框架调用的三种方法:ItemStream#open(ExecutionContext context)
-在开始处理数据之前将调用此方法,以允许组件打开任何必需的资源并重置以前可能在以前的运行中存储的任何状态。ItemStream#update(ExecutionContext context)
-通过执行允许组件在发生故障时保存任何状态的步骤来定期调用此方法。ItemStream#close()
-提供此方法以在处理完成后清除所有资源。
在ItemStream
选项中,您将重新初始化Map
中的每个ItemStream#open
,并可能在ItemStream#close
中对其进行清理。
您可以在此处阅读有关步骤作用域组件的更多信息:https://docs.spring.io/spring-batch/4.0.x/reference/html/step.html#step-scope
您可以在此处阅读有关ItemStream
界面的更多信息:https://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/item/ItemStream.html