easyexcel 导出 代码翻译converter_java导出Excel避免OOM的方案

d6cdb1c460aa1211123284912f932f2e.png

最近手里维护公司一个旧项目,导出excel的时候偶尔会OOM,堆内存溢出。通过本地重现,使用jvisualVM工具分析堆空间后发现,某个实例数所占用极高,上传5M的文件竟然产生了近100M的该实例,听说poi吃内存,但实际分析下来还是蛮惊讶的。

而网上关于excel导出OOM的方案有很多种,包括apache对poi的写改进,然而这个不是我们想要的,最终采用的是ali的easyExcel。为啥使用easyExcel能解决OOM呢,原来我们一次性加载到内存的excel数据,虽然不大,但是一次性读取那么多行和列,实际上没有必要,我们可以采取分批次读取,然后清空之前的读缓存来实现内存的最大化利用,这样读再大的文件也不用害怕了,只是读取的批次多一点,时间处理长一点罢了。

以下是我本地进行测试对比的过程,为了更好的显示出效果,我设置了此次进程的最大堆使用时168M,idea的启动配置如下。(为啥是168M大家可以思考以下,后面JVM分析工具里也可以看得出)

d6738999586da01089a18ab9d1201c46.png

上面配置了HeapDumpPath是在OOM后将堆栈信息输出到后缀为hprof的文件中,而VisualVM工具为我们提供了该格式文件的读取分析。

ok,运行,然后点击下载,同时打开我们的VisualVM工具,实时分析下载过程的内存占用,因为我事先控制了堆大小,所以此次试验用poi方式导出是一定能看到OOM的,接下来我们就观察这个过程吧。

74f02c664a215c8f8fb5b9ac9155ff7c.gif

在我点完postman后,old区很快就满了,后面我们发现GC的频率已经跟不上产生对象的速度了,98%的时间在GC而可用空间一直不到2%,最终OOM,我们也得到了堆日志hprof文件

java.lang.OutOfMemoryError: Java heap space

Dumping heap to D:/java_pid39344.hprof ...

Heap dump file created [284891634 bytes in 1.294 secs]

去D盘找到该文件 导入到VisualVM里进行分析。如下所示

16ca8cac9a3d55341b02c0d2c2ab8519.png

很明显发现前两个实例分别是apache.xmlbeans.impl.store下的Xobj实例,这么多实例数用了多大内存呢?

25363c44ff0162b07a85c2e3c42300c2.png

额,接近100M,而我们上传的文件只是5M大小的excel。可以说非常吃内存了。

下面看看EasyExcel的表现怎么样。

开始之前,注意到

EasyExcel · 语雀​www.yuque.com
4b7f5f5ae145e801b328f675d9a1d7f1.png

里有句话:

64M内存1分钟内读取75M(46W行25列)的Excel


可以说很牛了。根据上面的条件,我上传的文件是5M,堆内存是168M,easyExcel应该可以轻松应对。

4ae1b7f23b6dbe9cda0d36208d13efae.gif

再看下核心代码,除了dao层的代码会与官方demo不一样,其他都可以照搬。

d31d61f320ce77654143012c45c3b53f.png

669b77c348f3dab5adcd03b94d2fb309.png

通过对比,很容易看出easyExcel的性能更优。

-------------------------- 我是分割线 -------------------------------

欢迎加我微信交流

https://u.wechat.com/EE_j6UlJrr2mIcyMqpI1aAc (二维码自动识别)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值