You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Batch合并大文件时Step2报Java堆内存溢出问题求助

问题根因
  • 从报错栈可以看出OOM发生在FlatFileItemWriter.write方法内部的StringBuilder扩容阶段,本质是单次加载到内存待写入的数据量超过了JVM堆上限。
  • 你当前的Step2配置没有限制单次处理的数据量:如果Step的chunk size配置过大甚至未做合理配置,MultiResourceItemReader会持续读取临时文件的内容到内存,攒满一个chunk才会触发写入,单临时文件就超过500M,全量加载到内存必然触发堆溢出。
解决方案

方案1:调整chunk配置(成本最低,无需修改业务逻辑)

直接修改Step2的chunk大小,配置为较小的固定值,比如chunk-size="100",保证每次只读取、处理、写入100行数据,处理完就释放内存,内存占用会稳定在可控范围。

方案2:禁用FlatFileItemWriter的内存缓冲

给flatFileItemWriter新增如下配置,关闭默认的内存缓冲,数据直接写入磁盘,避免缓冲累积太多内容占用内存:

<property name="bufferWriter" value="false"/>

方案3:改用NIO零拷贝拼接文件(内存占用最低)

如果不需要对临时文件内容做额外处理,完全可以放弃Spring Batch的读写组件,直接用JDK NIO的零拷贝能力拼接文件:

  1. 先向目标文件写入header内容
  2. 依次读取每个临时文件,用FileChannel.transferTo直接把临时文件的字节内容追加到目标文件,全程不需要把文件内容加载到JVM堆内存
  3. 最后写入footer内容
    这种方式处理GB级别的文件也不会出现OOM问题。
关于MultiResourcePartitioner的说明

这个组件是用来做多分区并行处理的,核心作用是提升处理速度,不能解决你的内存溢出问题。而且你当前Step2的目标是写入单个文件,多线程并行写入同一个文件会出现内容顺序错乱、覆盖的问题,不适合你的场景。

内容的提问来源于stack exchange,提问作者Salim Rahmani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 04:06:10