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卡死

优化后发布可以正常导出了

一些误区

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

 

 

posted @ 2022-04-07 16:29  意犹未尽  阅读(441)  评论(0)    收藏  举报