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

写入CSV文件致JVM崩溃,千万级报表生成场景优化方案咨询

优化1000万条记录CSV导出的内存问题方案

哇,一次性加载1000万条Java对象再写CSV,服务器不崩才怪!这绝对是内存瓶颈的典型场景,我给你分享几个在实际项目里跑通的优化思路,核心就是避免一次性把所有数据塞进内存:

1. 数据库层面开启流式查询,分批取数

不要直接执行SELECT * FROM table把所有数据拉到内存里,改用流式/分页的方式获取数据:

  • 用JDBC的话,可以给Statement设置statement.setFetchSize(Integer.MIN_VALUE),让数据库驱动分批返回结果集,而不是一次性加载所有数据到内存。
  • 用JPA/Spring Data的话,返回Stream<T>类型(比如Spring Data的@Query方法返回Stream<User>),或者使用ScrollableResults滚动读取结果,每次只加载少量数据。

2. 配合Super CSV的逐行写入,边读边写

Super CSV本身支持逐行写入,完全不需要缓存所有对象。结合上面的流式查询,实现**“读一条,写一条”**的流水线:

// 伪代码示例
try (ICsvBeanWriter writer = new CsvBeanWriter(new FileWriter("report.csv"), CsvPreference.STANDARD_PREFERENCE);
     Stream<DataRecord> dataStream = dataRepository.streamAllRecords()) { // 流式查询
    writer.writeHeader(DataRecord.class);
    for (DataRecord record : dataStream) {
        writer.write(record, DataRecord.class); // 逐行写入,内存仅存当前对象
    }
}

这样堆内存里永远只有当前处理的几条数据,内存占用会降到极低。

3. 跳过Java对象转换,直接从ResultSet写CSV

如果你的业务不需要把数据库字段转换成Java对象,可以直接用Super CSV的CsvResultSetWriter,把ResultSet的内容直接写入CSV,省掉对象实例化的内存开销:

try (CsvResultSetWriter writer = new CsvResultSetWriter(new FileWriter("report.csv"), CsvPreference.STANDARD_PREFERENCE);
     ResultSet rs = statement.executeQuery("SELECT * FROM large_table")) {
    writer.write(rs); // 直接从ResultSet写数据,无需中转对象
}

这会进一步降低内存占用,效率也更高。

4. 邮件附件的内存优化

生成CSV后发送邮件时,不要把整个文件读进内存再作为附件发送,用FileDataSource直接关联文件:

MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.setDataHandler(new DataHandler(new FileDataSource("report.csv")));
attachmentPart.setFileName("report.csv");

如果文件超大,还可以先把CSV压缩成ZIP包再发送,既减少文件体积,也降低传输时的内存压力。

5. 异步处理,避免阻塞主线程

把导出任务放到异步线程或者任务队列里(比如Spring的@Async、Quartz),这样用户发起请求后不用一直等待,服务器也不会因为长时间的导出任务占用核心线程影响其他业务。导出完成后再给用户发邮件通知即可。

另外你提到的SXSSFWorkbook是POI处理大Excel的方案,它通过临时文件缓存超过内存阈值的行来避免溢出,但CSV的结构比Excel简单得多,完全不需要这么重的方案,流式读写就足够解决问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:58:18