poi导致内存泄露分析

poi导致内存泄露分析

背景

最近线上的机器偶尔会出现cpu打满的情况,内存也很吃紧,导致影响系统的正常运行。如下:
poi导致内存泄露分析_第1张图片
poi导致内存泄露分析_第2张图片
poi导致内存泄露分析_第3张图片
poi导致内存泄露分析_第4张图片

可以看出,已经严重影响到线上程序的运行了。

分析

用jmap打出对应的dump文件并用MAT工具打开。
poi导致内存泄露分析_第5张图片
很明显发生了内存泄露。
观察一下支配树。
poi导致内存泄露分析_第6张图片
可以看出,占用内存最多的是char[]数组对象,总共有700+万个。其次是XSSFSheet,共应用了300+mb的对象。
我们再看看当时的线程栈是怎样的。
poi导致内存泄露分析_第7张图片
频繁出现poi的相关类很明显有问题。
查看代码,这是解析上传的excel相关的代码。
是不是上上传的excel大小太大了呢?
poi导致内存泄露分析_第8张图片
看一看出poi内部是用treemap存储列和行信息的。
我们分别打印一下行数和列数
poi导致内存泄露分析_第9张图片
poi导致内存泄露分析_第10张图片
发现这是一个有234行和16384列组成的excel,按照预期,我们要求上传的excel只需要有一列就可以了。除此之外,表面上看excel也不是很大啊。
我们尝试创建一个这样的excel,并上传。
在这里插入图片描述
问题复现了
我们来看看excel有多大,只有15mb,15mb却用了2Gb左右的内存来解析,经过排查,排除了代码的问题。那么可能出错的就只有poi本身了。
经过调查,poi分为用户模式和sax模式来解析excel,用户模式适合处理小数据量的excel,sax适合用来存储数据量的excel,而项目中用的是用户模式,改变为sax模式或者限制上传的excel大小即可解决。
具体poi的相关知识这里不再细说。

你可能感兴趣的:(踩过的坑)