一、核心工具选型:流式处理框架
1. 使用EasyExcel(推荐)
阿里巴巴开源的EasyExcel基于流式读写设计,通过逐行处理数据避免内存堆积。
优势:
内存占用低,支持百万级数据导出;
内置分页写入、自动压缩等优化功能。
示例代码(分页写入):
java">ExcelWriter excelWriter = EasyExcel.write(fileName, Data.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();
int batchSize = 10000;
List<Data> dataList;
int pageIndex = 0;
do {dataList = getDataByPage(pageIndex++, batchSize); // 分页查询excelWriter.write(dataList, writeSheet);
} while (dataList.size() == batchSize);
excelWriter.finish(); // 必须关闭资源[6,10](@ref)
2. Apache POI的SXSSF模块
适用于需要复杂Excel格式的场景,通过限制内存中保留的行数实现流式处理。
示例代码:
java">SXSSFWorkbook workbook = new SXSSFWorkbook(100); // 内存保留100行
SXSSFSheet sheet = workbook.createSheet("Sheet1");
for (RowData data : dataStream) {Row row = sheet.createRow(rowNum++);// 填充数据并定期清理内存if (rowNum % 100 == 0) sheet.flushRows(100); // 持久化到磁盘
}
二、技术优化策略
1. 分页查询与分批处理
数据库分页:通过LIMIT offset, size分页查询,避免一次性加载全量数据。
MyBatis流式查询:结合ResultHandler逐行处理数据,减少内存占用。
java">userMapper.export(new ResultHandler<User>() {@Overridepublic void handleResult(ResultContext<? extends User> context) {User user = context.getResultObject();// 每积累1000条写入Excelif (dataList.size() == 1000) {excelWriter.write(dataList, writeSheet);dataList.clear();}}
});
2. 内存管理优化
JVM参数调整:增大堆内存(如-Xmx4G),启用G1垃圾回收器。
关闭非必要功能:禁用EasyExcel的自动列宽计算、样式缓存等。
java">EasyExcel.write(fileName).registerWriteHandler(new SimpleWriteHandler()) // 禁用自动列宽.sheet("Sheet1").doWrite(dataList);
3. 异步与文件处理
异步导出:将导出任务提交到线程池,避免阻塞主线程。
临时文件与压缩:将中间结果写入临时文件,导出完成后压缩或上传OSS。
三、架构级解决方案
1. 分布式处理
将数据拆分到多个节点并行处理,通过MapReduce或Spark生成多个Excel分片,最终合并。
2. 内存映射文件(MappedByteBuffer)
适用于超大数据(如数亿行),通过直接操作文件内存映射减少JVM堆压力。
java">try (FileChannel channel = FileChannel.open(path, StandardOpenOption.WRITE)) {MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024 * 1024);// 直接操作buffer写入数据
}
四、代码设计规范
资源释放:确保ExcelWriter、SXSSFWorkbook等对象调用finish()或dispose()关闭。
对象复用:避免循环内频繁创建对象,使用对象池或静态对象。
数据简化:导出时仅包含必要字段,避免嵌套对象和复杂结构。
五、性能验证与监控
压力测试:使用JMeter模拟百万级数据导出,观察内存峰值和GC频率。
监控工具:通过VisualVM或Arthas分析内存泄漏点,优化高频对象创建。
总结
彻底解决内存溢出需综合工具选型(如EasyExcel/SXSSF)、分页处理、JVM调优及代码规范。对于超大数据场景,可结合异步导出、分布式处理或内存映射文件进一步优化。实际项目中需根据数据量级和硬件资源选择合适的组合方案。