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卡死
优化后发布可以正常导出了
一些误区
这个场景其实原有对象内存占用非常小,但是原有对象引用了字符串对象导致长期得不到释放
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
2018-04-07 java线程池理解
2018-04-07 java里面的队列
2018-04-07 CopyOnWriteArrayList