MAT(Memory Analyzer Tool)使用心得(与实例使用方法)

实例链接:

https://my.oschina.net/flashsword/blog/265442

http://www.blogjava.net/rosen/archive/2010/06/13/323522.html

起因:最近在跟踪产品的性能问题,期间主要问题体现在JVM的内存回收问题,使用MAT工具进行JVM内存分析(也可对android 的应用内存分析)

问题描述

  • 1、部分后端服务在运行一段时间后会突然年老代会变为100%

  • 2、部分后端服务定期出现年轻代GC情况,耗时超过2S

问题1解决步骤

  1. 利用jmap指令(jmap -dump:format=b,file=文件名 PID)生成内存快照文件。文件名支持相对路径和绝对路径,PID指Java应用的进程ID,可通过JPS指令获取,在有些时候该指令无法直接生成内存快照,需要额外补充-f,原因会在稍后的文章中说明。

  2. 在官网下载MAT独立包(推荐64位,并修改MemoryAnalyzer.ini文件中的-Xmx,确保其值大于你的内存快照文件大小,否则MAT打开内存文件会报内存溢出),打开之前保存的内存快照文件

  3. 打开后,直接选择leak suspects选项(该选项表示MAT会自动帮我们分析内存泄漏最可能的类),分析完后类比下图(图片来自网络)

  4. 一般来说,该报告会告诉我们最可能泄露的类和相关实例,我们点进打开后,对Retained Heap最大的实例再点击选择outGoing references(当前对象,引用的外部对象),即可查看该实例中引用了哪些对象,一直没释放,从而导致该实例占了不少内存

  5. 根据步骤4基本就可以确认,究竟是哪些对象实例强引用未能释放,从而导致内存持续上涨直至频繁FGC,这时候就可以拉上开发的童鞋根据代码进行分析

  6. 回到问题的原点,这次的问题发生的原因是:多例模式下,大量的对象被加载到OSGI的核心容器中,从而导致大并发情况下,导致内存出现泄漏,最后内存溢出

问题2解决步骤

  1. 分析步骤与问题1并无偏差,但奇怪的现象是生成的报告中任何对象的实例的大小都很小,且总和与实际的内存文件相差甚远

  2. MAT默认是只分析reachable对象实例,所以在"Preferences=>Memory Analyzer"中勾选"Keep Unreachable Objects",删除索引文件Dump同路径下的所有".index",即可看到所有的对象,再根据上述步骤4进行分析

  3. 此时发现某个对象实例,其某个属性List无比庞大(size>10000)

  4. 后经与研发同事分析得知,某些查询动作会入库,从而导致日积月累的情况下,查询时就会创建一个额外的对象,引发频繁的young gc,甚至full gc

问题反思

  • 版本测试时,除了常规的功能测试外,还要对核心业务进行性能测试,根据时间进度可适当切割,但不能缺失

  • 场景测试时,除了常规的场景测试外,还需考虑当前的数据库量级,若当前表量级较大,业务模块中的sql语句是否有做limit等限制

  • 生产环境上应对应用做相关监控,除了日常的服务器本身性能监控外,还需要对应用本身的各项指标监控,例如:GC次数、GC耗时甚至young、s0、s1、pem、old等不同年代的监控。根据日常的监控图表来判断当前服务是否正常

  • 一般来说,young gc的次数要大于old gc和full gc,且耗时是毫秒级。不然,则有可能:young年代设置过小,应用创建了过大的对象,存在大量强应用的对象实例等

参考资料

https://my.oschina.net/flashsword/blog/265442

http://www.blogjava.net/rosen/archive/2010/06/13/323522.html

`MATMemory Analyzer Tool)`是一个强大的内存分析工具,专用于Android应用的内存泄漏检测。以下是使用`MAT`检查服务内存泄漏的基本步骤: 1. **收集堆转储(Heap dump)**:首先,你需要在设备或模拟器上生成一次堆转储数据。在开发者选项中开启"USB调试",然后通过`adb`连接到设备,执行`dumpsys meminfo [进程名] > heapdump.hprof`,或者在Android Studio中选择"Profiler" -> "Heap Profiler" 来生成堆转储文件。 2. **加载堆转储**:将生成的`.hprof`文件导入`MAT`。在`MAT`界面,点击"Open.heap"或"Open heap dump file"按钮,选择堆转储文件。 3. **识别泄露的对象**:在`MAT`的"Leak Suspects"视图中,会列出那些引用次数超过预期、长时间未被垃圾回收的对象。它们通常是导致内存泄漏的原因。 4. **跟踪引用路径**:对于疑似泄漏的对象,点击它进入"Object Heap"视图,查看其引用链。你可以通过追踪强引用、软引用等不同类型的引用,找到内存泄漏的具体源头。 5. **分析和服务关联**:确定了泄漏的对象后,检查它们是否与你的`LatinIME`服务有关联。例如,看是否有对Service实例的强引用,或者服务内部的数据结构可能导致长期占用内存。 6. **修复内存泄漏**:根据分析结果,找出内存泄漏的原因,修改代码,比如解除不必要的引用、定期清理缓存等。 记住,虽然`MAT`可以帮助发现内存泄漏,但它并不是万能的,有时还需要结合其他日志和代码审查来确认问题所在。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值