android 如何分析应用的内存(十七)——使用MAT查看Android堆

这篇具有很好参考价值的文章主要介绍了android 如何分析应用的内存(十七)——使用MAT查看Android堆。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

android 如何分析应用的内存(十七)——使用MAT查看Android堆

前一篇文章,介绍了使用Android profiler中的memory profiler来查看Android的堆情况。
如Android 堆中有哪些对象,这些对象的引用情况是什么样子的。

可是我们依然面临一个比较严峻的挑战:不管是app开发者,还是内存分析者而言,堆中的对象,非常之多,不仅有Android 原生的类,还有第三方库使用的类。这些类在使用过程中,也可能因为有较大的shallow size 或者retained size而混淆内存的分析。

为了解决这样的问题,我们更希望,通过不同时间点的堆,进行差分比较。即在时刻t1生成的堆heap1和t2时刻生成的堆heap2进行相互比较。

为此,我们将介绍java开发中重要的内存分析工具MAT。

MAT使用前的准备

在上一篇文章中,我们使用AS捕获了堆,现在我们需要将其导出,用在MAT工具上。如下图:
android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

接下来将Android保存的heap dump进行格式转换,以满足MAT的需求。转换格式的工具在Android SDK中。如下:

/Users/biaowan/Library/Android/sdk/platform-tools/hprof-conv ./mat/memory-test_malloc_int\[\].hprof mat_test1.hprof

android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

MAT的使用

打开MAT之后,进入菜单栏->File->Open File。然后选择刚才转换之后的mat_test.hprof文件。如下图
android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

可见,主界面显示一个overview的界面,该界面用英文详细表述了具体细节,不在赘述。下面解释上图的八个标记。

  • 标记1:打开overview 界面。即上面的主界面。

  • 标记2:打开当前堆中的对象分布情况,默认按照类名进行排序。右键可以进行相应操作,各个操作什么意思,已经标明。如下图
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

  • 标记3:显示本heap中的所有dominator tree(注意:dominator tree,已经在上一篇文章中介绍:android 如何分析应用的内存(十六)——使用AS查看Android堆:http://t.csdn.cn/GTWpR). 而各个对象应该怎么查看其对应的dominator tree。见标记2对应的右键说明。

  • 标记4:Open Object Qurey Language,类似于使用SQL语句进行查询。因为MAT提供的菜单功能已经完全够Android使用,因此本文不再介绍

  • 标记5:展示线程的名字,堆栈,本地变量等。但是Android 没有提供这个功能,因此无法使用

  • 标记6:打印各种报告,如下图标记
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

  • 标记7:即为标记2中,右键支持的各种操作,详见标记2

  • 标记8:搜索按钮,可以按照地址进行搜索

为了能够详细说明,如何操作MAT,下文将会以各种问题作为模板,详细介绍操作过程

问题1:如何查看某个类有哪些对象

  1. 点击标记1,打开所有类的列表。
  2. 在第一行,键入需要查找的类,或者按照不同的大小进行排序和过滤
  3. 选中类,然后点击右键,选择List Objects.然后按照需求列出各个对象
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

问题2:如何查看某个对象到GC root的引用链

  1. 选中某个对象,右键选中Paths to GC root
  2. 再次选中exclude all xxx references
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

可见整个引用链清晰明了,不在绘图说明

问题3:如何查看对象的Dominator tree(支配树)

  1. 选中对象,右键选择Java Basics
  2. 再次选中Open in Dominator tree
  3. 在弹出的框中,选择finish。默认以对象排序
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

从图中可以看到TaskRunable对象直接支配两个对象,一个int数组,一个弱引用

问题4:如何查看一个对象的直接支配者

  1. 选中对象,然后右键,选择immediate dominator
  2. 在弹出框中,选择finish
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

可以看到我们选中的TaskRunable对象的直接支配者是一个Task对象

问题5:如何查看类加载器,是否重复加载同一个类

  1. 点击标记1,打开overview界面
  2. 滚动界面到最底下
  3. 选择Duplicate classes
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

问题6:如何查看堆中,最占内存的部分

  1. 点击标记1,打开overview界面
  2. 滚动至最底下
  3. 选择Top cosumer
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

从图中可以看到,分别按照对象,类,类加载器,包名列出了最占内存的部分

问题7:如何查看堆的报告

  1. 点击标记6.选择Heap dump overview
  2. 在对报告中,点击table of content 查看内容表(该字段,在报告的底部)
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

从中也可以直接查看最占内存的对象

问题8:如何进行泄露检查

  1. 点击标记6,选择Leak Suspect
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

从图中可以看到,有三个怀疑的对象,往下滚动,可以看到三个怀疑对象的详细细节,如下
android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

图中,简要说明了Task类,有2100个实例,占了29.51%的内容。点击details它会显示相应的引用链路径。可清晰看到GC root的整个引用链。

多个Heap进行差分分析,查找内存问题

为了一步步演练,如何使用多个heap进行差分分析,我们选择上一篇文章方案2中的例子:android 如何分析应用的内存(十六)——使用AS查看Android堆:http://t.csdn.cn/JYGFC。然后在同一个进程的两个不同时刻,分别选取不同的heap,分别叫as_heap1.hprof和as_heap2.hprof.

场景1:MAT 自动分析两个堆之间的内存泄露

  1. 按照上文提及的hprof-conv工具,将as_heap1.hprof,as_heap2.hprof分别转换为mat_heap1.hprof,mat_heap2.hprof。然后用mat工具将其打开。

  2. 打开第二个heap的overvie操作栏,即标记1。滚动到最底部

  3. 选择Leak suspects by Snapshot comparision.

  4. 在弹出的框中,选择mat_heap1.hprof。然后点击finish。让mat_heap2.hprof与mat_heap1.hprof做差分分析,然后给出一个报告,如下(需要等待一段时间)
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

从图中可以看到,怀疑com.example.test_malloc.Task对象泄露,它有4900个对象,占整个堆的49.26%。点击details可以看到这个引用链,如下图
android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

从图中可以看到,Task被DeviceManager的listener所持有,导致GC无法回收。所以找到了内存泄露点。

场景2:无法自动分析时,手动分析

当两个heap堆,间隔时间较短,泄露的对象,占据整个堆的空间较小,此时mat无法进行自动分析。此时我们可以手动分析。

接下来,我们用时间间隔较小的两个堆,分别叫mat_heap3.hprof和mat_heap4.hprof

注意:mat_heap3.hprof和mat_heap4.hprof是用AS 重新抓取的时间间隔较近的两个堆

  1. 用mat打开mat_heap3.hprof,和mat_heap4.hprof

  2. 按照问题6,输出消耗内存最大的部分。下面是mat_heap3.hprof的报告。
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

从中,我们看到,占据内存最大的首要对象是int数组。接下来我们手动分析两个堆中的int数组之间的差距——即mat_heap4.hprof比mat_heap3.hprof多了哪几个int数组

  1. 点击mat_heap3.hprof的统计信息,即标记2.然后选中int[]。右键列出所有的对象。如下图
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

  2. 点击操作历史记录栏,右键list_objects… 然后点击add to compare basket。如下图
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

  3. 因为我们需要比较两个heap堆的int[]情况,因此选中mat_heap4.hprof之后,按照步骤3,4做同样操作。将会在compare basket窗口两个需要比较的对象。然后点击感叹号,开始比较即可。如下:
    android 如何分析应用的内存(十七)——使用MAT查看Android堆,android  内存分析,android mat,android分析两个堆,Android堆比较,mat泄露报告,mat查看引用链

对测试结果,进行简单排序,shallow_heap #1 升序排列。即可展示heap3中没有而heap4中具有的对象。这也是从抓取heap3时刻,到抓取heap4时刻之间,堆中多出来的int数组对象。为前排的10个对象。

按照前文的问题2即可查看其引用链,从而分析被谁持有,为何没有被释放掉。

在第2步中,输出的top comsumer除了int数组以外,还有其他的对象,因此按照步骤3,4,5即可进行两个堆的比较。我们已经以int[]为例子,做了详细说明,就不再一一比较。

除了使用top comsumer辅助定位需要比较的对象以外,还可以对任何怀疑的对象进行比较。步骤完全相同。

至此,MAT的使用介绍完毕。

MAT弥补了AS在内存分析上的如下不足:

  • 无法自定义Retained Set(这对于大型应用很有用)
  • 无法进行地址查找
  • 无法进行堆之间的比较
  • 无法按照需要进行排序
  • 无法按照需要进行过滤等

虽然MAT已经足够强大,但是依然还有一个内存问题,悬而未决——怎么才能知道这些内存泄露是由哪一个线程触发,它们又有怎样的调用栈?

在多线程编程中,对象的泄露,即可能是对象之间的引用不合理,也可能是线程之间的逻辑不合理,如生产线程和消费线程不够合理等等。MAT无法解决Android线程所带来的内存泄露。

接下里,请期待如何用工具找到这种多线程带来的内存泄露。文章来源地址https://www.toymoban.com/news/detail-643555.html

到了这里,关于android 如何分析应用的内存(十七)——使用MAT查看Android堆的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • android 如何分析应用的内存(九)——libc回调

    接上文,在前面文章中,介绍了bionic库提供的各种功能,其中包括: 自定义的malloc malloc hook malloc debug 接下来,介绍的是bionic库提供的libc回调功能,它可以通过代码获得所有的内存分配情况 。 前情提要:在使用libc回调的时候,依然需要打开malloc的调试功能,见上一篇文章中

    2024年02月12日
    浏览(36)
  • android 如何分析应用的内存(十五)——Visual Studio Code 调试Android应用

    在上一篇文章介绍了jdb调试java应用 接下来介绍用UI界面调试java应用,达到同jdb一样的效果。 同样的UI界面有很多选择,如Eclipse,Android Studio,Visual Studio Code.因为Android Studio的诸多不便,结合自身的使用习惯,这里推荐并介绍Visual Studio Code 安装必要的插件 在插件市场中,搜索

    2024年02月14日
    浏览(51)
  • Java 内存溢出(二)使用 MAT 分析 .hprof 内存映像文件

    .hprof 文件: 是 java 项目的 Heap Dump 文件,也叫内存映像文件、内存快照文件,可以存放一个 java 进程在某个时间点的内存快照。生成 Heap Dump 文件的方式有两种:一是使用 jmap 命令手动导出,二是启动脚本中添加 -XX:+HeapDumpOnOutOfMemoryError 参数自动导出。本文中只涉及第二种。

    2023年04月08日
    浏览(69)
  • android 如何分析应用的内存(八)——Android 7.0以后的malloc debug

    接上文,介绍六大板块中的第三个————malloc调试和libc回调 上一篇文章中,仅仅是在分配和释放的时候,拦截对应的操作。而不能进一步的去检查内存问题。比如:释放之后再次使用指针,内存泄漏,内存损坏等等。 在这篇文章中,将会介绍malloc调试技术,它可以对nat

    2024年02月10日
    浏览(44)
  • Eclipse内存分析器 Java内存分析工具MAT(Memory Analyzer Tool)的介绍与使用

    =============================================------------------------ 然后我将堆内存文件转储,就告诉我内存泄漏,分析结果如下,请帮我前后理解关系。我需要向领导汇报。7 instances of “org.apache.catalina.loader.ParallelWebappClassLoader”, loaded by “java.net.URLClassLoader @ 0x4c0008ae8” occupy 17,693,472 (1

    2024年04月26日
    浏览(53)
  • eclipse memory Analyzer(MAT) 内存泄漏分析

      1.1软件下载         Eclipse IDE,它非常有用。因为Memory Analyzer在分析堆内存的时候比较耗费内存,而Eclipse IDE本身又是比较耗费内存的,所以推荐使用独立安装的Memory Analyzer。 安装包地址:https://www.eclipse.org/mat/downloads.php 独立安装的Memory Analyzer的独立版本所需的最低Ja

    2024年02月14日
    浏览(50)
  • 【开发篇】四、MAT堆内存分析(Memory Analyzer Tool)

    内存溢出后,分析泄露的思路是: 在OOM前,将整个堆内存保存成一个hprof文件 MAT打开hprof文件,MAT自行分析可疑对象 添加JVM参数: 模拟个OOM: 在MAT里打开hprof文件: 报错: 很清晰了, 下载JDK17或者换一个低版本的MAT(适配你配置的JDK版本的MAT) ,我当前是JDK11,下载地址【

    2024年01月19日
    浏览(54)
  • 一文深度讲解JVM 内存分析工具 MAT及实践(建议收藏)

    1. 前言 熟练掌握 MAT 是 Java 高手的必备能力,但实践时大家往往需面对众多功能,眼花缭乱不知如何下手,小编也没有找到一篇完善的教学素材,所以整理本文帮大家系统掌握 MAT 分析工具。 本文详细讲解 MAT 众多内存分析工具功能,这些功能组合使用异常强大,熟练使用几

    2024年02月09日
    浏览(42)
  • mac pro m1:安装dump文件内存分析工具——MAT

    本文主要针对mac m1下安装Jprofiler进行讲解,安装核心步骤同样适用于其他系统 如果使用的是eclipse可以在插件中直接安装MAT,因为我使用的是idea开发,所以选择独立安装MAT工具 1、下载地址:https://www.eclipse.org/mat/downloads.php 选择你需要的版本,这里我选择的mac arm架构版,注意

    2024年02月06日
    浏览(40)
  • 如何使用KoodousFinder搜索和分析Android应用程序中的安全威胁

    KoodousFinder是一款功能强大的Android应用程序安全工具,在该工具的帮助下,广大研究人员可以轻松对目标Android应用程序执行安全研究和分析任务,并寻找出目标应用程序中潜在的安全威胁和安全漏洞。 在使用该工具之前,我们首选需要访问该工具的【开发者门户】创建一个

    2024年02月13日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包