freemarker导致内存泄露问题分析排查
说明
测试环境出现非常慢,测试说执行过工单word导出就出现这种问题
排查步骤
1.查看机器cpu和内存 正常
2.排查gc回收 发现一直在触发full gc 同时每次full gc后释放的空间很小
jstat -gc 10755
3.dump堆信息进行分析
jmap -dump:format=b,file=/Users/liqiang/Desktop/logs/heap.hprof pid
4.先通过Vm查看
根据大对象名字看不出什么问题

5.使用MAT 导入dump文件进行分析

6.前面3个都是相同的堆栈看业务代码是导出 高度嫌疑

7.点击Details当前执行线程运行引用的对象信息
可以发现freemarker.core.SimpleCharStream 为大对象类

8.可以通过右键查看当时对象的引用信息和成员变量信息

9.一般查看内存泄露都是看引用refrences
可以看出源头是template 的parser引用tokenSource ....

10.MAT我感觉不直观可以使用VM


11.跟源码发现parse在初始化后就置空了销毁了,理论上垃圾回收期会回收

12.看线程堆栈确实是在template 构造函数触发的大对象占用得不到释放

13.最后根据业务代码定位到 调用了2次fremakker渲染

14.最后怀疑是不是第一次已经填充了数据,整个结果非常大 因为含有图片。图片针对word导出是填充的图片的base64的数据
第二次根据第二次的结果再进行渲染因为太大 导致异常在template卡死
优化后发布可以正常导出了

一些误区
这个场景其实原有对象内存占用非常小,但是原有对象引用了字符串对象导致长期得不到释放

浙公网安备 33010602011771号