一次MAT工具的使用过程

背景

前阵子放假回来组内其他同事发现线上出现了机器频繁重启问题,协助进行问题排查。主要表现为cpu资源占用80%以上,同时jvm gc次数频繁。经过初步排查出是excel文件导入导致的,但并未找到关键代码,遂导出堆文件进行本地分析。

MAT (Memory Analyzer tool) 内存分析工具

MAT 能够对堆内存文件进行较详细分析的工具,主流的格式都支持,目前试过hprof,bin格式。以下为个人使用步骤

1.内存文件转储

首先需要将线上堆内存文件拉下来,由于堆文件较大,可能会搞崩内部系统,所以尽量先压缩再拉到本地

转储堆内存文件命令

ini 复制代码
jmap -dump:format=b,file=存储目录/文件名称.hprof <pid>

例如之前是转储在/logs目录下的

jmap -dump:format=b,file=/logs/dump.hprof java进程号

生成后可以进行压缩,再拉到本地,能压缩5-10倍左右

复制代码
tar -zxvf 文件路径 

2.内存文件分析

内存分析工具自己平时用的是Eclipse MemoryAnalyzer

相关页面:

excel问题一开始是从线上dump了一次内存文件,但因为相应的对象已经给回收完毕了,所以内存文件看不到存在异常的地方。之后组内推断出是某个excel引起的,在线上使用该excel发现内存跟cpu的确会同步飙升。

遂尝试本地调用该文件,拿到回收前的内存情况,看能能否找出具体的问题代码。

缩略图

通过缩略图可以看到,未被回收的内存有3.1G,其中3G的内存都跟一个名字叫 asyncBatchExecutor 的线程池有关系,这个线程池的确跟导入有关系

Histogram

用于查看对象类的内存占用情况。

Thread对象实际占用了超过3G的内存空间,猜测是上面说到的asyncBatchExecutor线程池。

点击类对象,右键选择List objects -》 outgoing references 查看引用该类的对象

可以看到的确是 asyncBatchExecutor 这个线程池引用的一个线程对象

可以看到,一个与xml相关的类,占用了超过1G以上的内存空间

一个与dom相关的类,占用了超过1G的内存空间

所以判断:

asyncBatchExecutor线程池中的一个thread对象,执行excel导入任务时,会创建大量的xml,dom相关的类对象,从而导致服务频繁gc

Leak Suspects

能够对内存中存在的问题做一些检测及推断

定位出了一个问题,跟asyncBatchExecutor有关,看下detail详细内容

内存空间大部分被dom,xml这两个类的对象占用了

通过thread Stack 找出这两种类对象生成的源头代码。 为poi包,WorkbookFactory类的create方法

解决方案

百度了下poi WorkbookFactory.create 的确会出现大量对象创建的问题。推测该方法除了解析excel文字外,还会解析一些excel格式,跟xml,dom有关系,相关代码存在bug导致创建大量对象。临时解决方案,先临时将poi版本进行升级,先避免问题再次发生。目前已经已经将该excel导入接口替换为用easyExcel进行导入了。

MAT工具使用参考网址

相关推荐
superman超哥13 小时前
路由的艺术:Rust Web 框架中的高效匹配与类型安全提取
开发语言·rust·编程语言·rust web框架·rust路由
superman超哥18 小时前
Rust 异步性能的黑盒与透视:Tokio 监控与调优实战
开发语言·后端·rust·编程语言·rust异步性能·rust黑盒与透视·tokio监控与调优
冬奇Lab19 小时前
【Kotlin系列04】类与对象基础:从Java Bean到Data Class的优雅蜕变
android·kotlin·编程语言
superman超哥20 小时前
Rust 异步编程的终极考验:Tokio 资源管理与清理
开发语言·rust·编程语言·rust异步编程·tokio资源管理与清理
superman超哥2 天前
Rust 异步时间管理核心:Tokio 定时器实现机制深度剖析
开发语言·rust·编程语言·rust异步时间管理核心·tokio定时器实现机制·tokio定时器
superman超哥2 天前
Rust 异步递归的解决方案
开发语言·后端·rust·编程语言·rust异步递归
superman超哥2 天前
Rust 异步并发核心:tokio::spawn 与任务派发机制深度解析
开发语言·rust·编程语言·rust异步并发核心·rust任务派发机制
superman超哥2 天前
Rust 异步并发基石:异步锁(Mutex、RwLock)的设计与深度实践
开发语言·后端·rust·编程语言·rust异步并发·rust异步锁·rust mutex
superman超哥2 天前
Rust 异步错误处理最佳实践
开发语言·rust·编程语言·rust异步错误处理·rust最佳实践
冬奇Lab2 天前
【Kotlin系列03】控制流与函数:从if表达式到Lambda的进化之路
android·kotlin·编程语言