easyExcel大数据量导出oom

文章讨论了easyExcel在处理大数据量时遇到的内存溢出问题,通过分批写入文件并手动回收数据对象,成功避免了OutOfMemoryError。作者还提到当数据行超过104万时,需考虑使用分sheet页导出以解决POI的限制。
摘要由CSDN通过智能技术生成
easyExcel大数据量导出
  • 异常信息
com.alibaba.excel.exception.ExcelGenerateException: java.lang.OutOfMemoryError: GC overhead limit exceeded
	at com.alibaba.excel.write.ExcelBuilderImpl.fill(ExcelBuilderImpl.java:84)
	at com.alibaba.excel.ExcelWriter.fill(ExcelWriter.java:185)
  • 原因,easyExcel在进行填充数据的时候比较耗内存容易造成oom
  • 解决方案,把数据分批写入文件,部分代码
        ExcelWriter excelWriter = null;
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            // 创建填充配置
            FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();
            excelWriter = EasyExcel.write(outputStream)
                    .withTemplate(templateIn).build();
            // 创建Sheet对象
            WriteSheet sheet = EasyExcel.writerSheet(0).build();
            // 分批导出
            int totalSize = dataList.size();
            // 每次导入条数
            int limit = 20000;
            // 共分的次数
            int totalPages = totalSize / limit;
            if (totalPages % limit > 0) {
                totalPages++;
            }
            for (int i = 0; i < totalPages; i++) {
                if (i == totalPages - 1) {
                    excelWriter.fill(dataList.subList(i * limit, dataList.size()), fillConfig, sheet);
                } else {
                    excelWriter.fill(dataList.subList(i * limit, limit * (i + 1)), fillConfig, sheet);
                }
            }
        } finally {
            if (null != excelWriter) {
                // 关闭流
                excelWriter.finish();
            }
            try {
                outputStream.close();
            } catch (IOException e) {
                log.error("关闭文件流失败");
            }
            try {
                templateIn.close();
            } catch (IOException e) {
                log.error("关闭文件流失败");
            }
        }
  • 验证:分批次写入文件,可以正常导出文件,并未出现oom
  • 在导出excel数据之后,fullGc的时候并未第一时间回收数据集合,可以在finally手动回收数据对象
finally {
            if (!CollectionUtils.isEmpty(dataList)) {
                dataList.clear();
            }
            if (null != excelWriter) {
                // 关闭流
                excelWriter.finish();
            }
            try {
                outputStream.close();
            } catch (IOException e) {
                log.error("关闭文件流失败");
            }
            try {
                templateIn.close();
            } catch (IOException e) {
                log.error("关闭文件流失败");
            }
        }
  • 在数据行数超过104万条的时候报错
    在这里插入图片描述
  • 1048576是poi的限制
  • 超过104万的话可以采用分sheet页导出的方式
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值