关闭

内存泄露排查步骤——内存优化(四)

标签: android内存泄露内存heap
1022人阅读 评论(0) 收藏 举报
分类:

转载请标明出处:http://blog.csdn.net/xx326664162/article/details/49949833 文章出自:薛瑄的博客

你也可以查看我的其他同类文章,也会让你有一定的收货!

Android Device Monitor分析heap

Android Device Monitor分析heap的总内存占用大小来初步判断是否存在泄露

  Android Device Monitor,类似于eclipse的DDMS
  1. 在Devices 中,点击要监控的程序。
  2. 点击Devices视图界面中最上方一排图标中的“Update Heap”
  3. 点击Heap视图
  4. 点击Heap视图中的“Cause GC”按钮
  5. 到此为止需检测的进程就可以被监视。

这里写图片描述

Heap视图中部有一个Type叫做data object,即数据对象,也就是我们的程序中大量存在的类类型的对象。在data object一行中有一列是“Total Size”,其值就是当前进程中所有Java数据对象的内存总量,一般情况下,这个值的大小决定了是否会有内存泄漏。

可以这样判断:
进入某应用,不断的操作该应用,同时注意观察data object的Total Size值,正常情况下Total Size值都会稳定在一个有限的范围内,也就是说由于程序中的的代码良好,没有造成对象不被垃圾回收的情况。

所以说虽然我们不断的操作会不断的生成很多对象,而在虚拟机不断的进行GC的过程中,这些对象都被回收了,内存占用量会会落到一个稳定的水平;反之如果代码中存在没有释放对象引用的情况,则data object的Total Size值在每次GC后不会有明显的回落。随着操作次数的增多Total Size的值会越来越大,直到到达一个上限后导致进程被杀掉。

MAT分析hprof来定位内存泄露的原因所在

要调试内存,首先需要获取HPROF文件,HPROF文件是MAT能识别的文件,HPROF文件存储的是特定时间点,java进程的内存快照。有不同的格式来存储这些数据,总的来说包含了快照被触发时java对象和类在heap中的情况。由于快照只是一瞬间的事情,所以heap dump中无法包含一个对象在何时、何地(哪个方法中)被分配这样的信息。

1、使用Android Studio获取HPROF文件(两种方法)

第一种:使用Android Studio同样可以导出对应的HPROF文件:

这里写图片描述

最新版本的Android Studio得在文件上右键转换成标准的HPROF文件,才可以在MAT中打开。

第二种:打开Android Device Monitor,类似于eclipse的DDMS

这里写图片描述
(我这里使用别人的DDMS图,和在Android Device Monitor的操作一样)

选择存储路径保存后就可以得到对应进程的HPROF文件。

  • 如果是用 MAT Eclipse 插件获取的 Dump文件,不需要经过转换则可在MAT中打开,Adt会自动进行转换。

  • Android Studio需独立安装的MAT,并使用Android SDK自带的工具(hprof-conv 位置在sdk/platform-tools/hprof-conv)进行转换

 hprof-conv xxx.xxx.xxx.hprof xxx.xxx.xxx.hprof 

转换过后的.hprof文件即可使用MAT工具打开了。

2、Android Studio的同学使用MAT独立软件打开

3、查询内存泄露的地方

第一种方式:

1、在Histogram图中,在如图的位置输入进行查询,如:activity
选择with incominng references ,分析持有此类对象引用的外部对象

这里写图片描述
2、选择with incoming references 进入下图,分析这些持有引用的对象的GC路径,图中子菜单的两个选项,表示去除Phantom Ref(虚引用)和Weak Ref(弱引用),原因参考这里

这里写图片描述

3、逐个分析每个对象的GC路径是否正常
这里写图片描述

从这个路径可以看出是一个antiRadiationUtil工具类对象持有了MainActivity的引用导致MainActivity无法释放。此时就要进入代码分析此时antiRadiationUtil的引用持有是否合理(如果antiRadiationUtil持有了MainActivity的context导致节目退出后MainActivity无法销毁,那一般都属于内存泄露了)。

第二种方式:

怀疑某个对象存在泄露后,可以通过OQL来进一步证明。OQL可以通过查询语法,来查询具体的对象信息,主要使用的是查询某个类的实例信息。
语法为:

select * from instanceof Class
例如,查询类com.yunos.tv.launchersdk.view.component.ScreenContainer的所有实例:     
select * from instanceof com.yunos.tv.launchersdk.view.component.ScreenContainer

得到的结果如图:

这里写图片描述

Class Name Shallow Heap Retained Heap
com.yunos.tv.launchersdk.view.component.ScreenContainer @ 0x443108e8 680 2,712
com.yunos.tv.launchersdk.view.component.ScreenContainer @ 0x42817648 680 16,289,472

图中说明com.yunos.tv.launchersdk.view.component.ScreenContainer这个类有两个实例,两个实例占用的内存大小分别为2,712和16,289,472。
如过实例的数量超出预期,说明存在内存泄露,如果实例所占内存的大小超出预期,说明这个实例内部的引用存在问题,可以进一步分析这个实例的具体信息。

更详细的介绍在这里 内存泄露排查原因及解决方法

MAT对比操作前后的hprof来定位内存泄露的根因所在

为查找内存泄漏,通常需要两个 Dump结果作对比,打开 Navigator History面板,将两个表的 Histogram结果都添加到 Compare Basket中去

1、第一个HPROF 文件(usingFile > Open Heap Dump ).

2、打开Histogram view.

3、在NavigationHistory view里 (如果看不到就从Window >show view>MAT- Navigation History ), 右击histogram然后选择Add to Compare Basket .

这里写图片描述

4、打开第二个HPROF 文件然后重做步骤2和3.

5、切换到Compare Basket view, 然后点击Compare the Results (视图右上角的红色”!”图标)。

这里写图片描述

6、分析对比结果

这里写图片描述

可以看出两个hprof的数据对象对比结果。
通过这种方式可以快速定位到操作前后所持有的对象增量,从而进一步定位出当前操作导致内存泄露的具体原因是泄露了什么数据对象。

转载:
https://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=400891536&idx=1&sn=0b6c629b0abe4a359d6552cd244c0c0c&scene=1&srcid=0303pbuNmzzdPnwQLozLrMip&pass_ticket=8HY76%2FaZXUVizdmMUJA7KW40UY8GIW54Sj85H1PLcNuzGxmipJ36D7AsqXOA%2BdRb#rd
http://www.jianshu.com/p/d8e247b1e7b2#

1
0
查看评论

通过windbg排查程序内存泄露

1.设置windbg工具内存跟踪gflags  -i memtest.exe +ust 2.运行一段时间通过调试器windbg attach中断 输入命令 !heap -s输出类似: 0:001> !heap -s 3.过段时间再次中断输入!heap -s,查看增...
  • u011391040
  • u011391040
  • 2016-06-14 16:22
  • 375

Linux 下几款程序内存泄漏检查工具

写这篇博客的原因呢是因为自己在编写基于Nginx磁盘缓存管理程序,目前已经进入测试阶段,关于这个程序的测试分为几个主要步骤:1.内存管理是否正确(因为这个程序本身开辟很多内存空间进行缓存管理,同时这个程序程序本身就是基于C/C++开发的,内存管理机制一直是程序员头痛的东西) 2.程序的健硕性如何(服...
  • youbingchen
  • youbingchen
  • 2016-07-23 10:15
  • 8248

如何检查内存泄露问题

简单说一下在没有工具的情况如何运用VC库中的工具来检查代码的内存泄漏问题。 一: 内存泄漏          内存泄漏是编程中常常见到的一个问题,内存泄漏往往会一种奇怪的方式来表现出来,基本上每个程序都表现...
  • sunnylion1982
  • sunnylion1982
  • 2012-11-15 14:29
  • 21550

内存泄露及检测

转载自:http://www.cnblogs.com/skynet/archive/2011/02/20/1959162.html “该死系统存在内存泄漏问题”,项目中由于各方面因素,总是有人抱怨存在内存泄漏,系统长时间运行之后,可用内存越来越少,甚至导致了某些服务失败。内存泄
  • xywlpo
  • xywlpo
  • 2011-09-25 14:36
  • 12726

几种内存泄露检测工具的比较

概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的、复杂的应用程序中,内存泄漏是常见的问题。当以前分配的一片内存不再需要使用或无法访问时,但是却并没有释放它,这时就出现了内存泄漏。尽管优秀的编程实践可以确保最少的泄漏,但是根据经验,当使用...
  • bluehawksky
  • bluehawksky
  • 2014-10-07 01:44
  • 14230

排查 Web App 的 JS 内存泄露小结

转载地址:https://testerhome.com/topics/3589 排查Web App的JS内存泄露小结 一、概述  所测试的项目是带角色交互的APP,其教师端是Hybird APP(主要控件是Native,页面内容基于Webview),学生端是一个基于W...
  • wanglha
  • wanglha
  • 2015-11-10 10:07
  • 604

内存泄露排查步骤——内存优化(四)

转载请标明出处:http://blog.csdn.net/xx326664162/article/details/49949833 文章出自:薛瑄的博客你也可以查看我的其他同类文章,也会让你有一定的收货!Android Device Monitor分析heapAndroid Device Mon...
  • xx326664162
  • xx326664162
  • 2015-11-26 17:20
  • 1022

通过一个小Demo学会java内存泄漏排查优化

在魔都奋斗的程序员GG 2017-05-07 18:36 前言---昨天小编写了一篇关于内存泄漏的文章,感谢昵称为“守望者之父”和“BombOfLove”,提出了新的问题。所以小编今天打算通过一个小Demo来和大家分享一下如何进行java内存泄漏排查优化,希望起到抛砖引玉的作用。 在...
  • u011277123
  • u011277123
  • 2017-05-12 13:38
  • 502

一个java内存泄漏的排查案例

这是个比较典型的java内存使用问题,定位过程也比较直接,但对新人还是有点参考价值的,所以就纪录了一下。 下面介绍一下在不了解系统代码的情况下,如何一步步分析和定位到具体代码的排查过程 (以便新人参考和自己回顾)   初步的现象 业务系统消费MQ中消息速度变慢,积压了200多...
  • aasgis6u
  • aasgis6u
  • 2017-02-08 16:39
  • 758

JS内存泄漏排查

可以利用chrome f12审查工具中的profile功能进行内存泄漏排查,点击take snapshot拍下堆内存的快照,对比相邻的两次快照就能得出哪些内存没有回收1.在控制台中新添加一个对象,观察profile中的变化:function Foo(name) { this.name = n...
  • Szu_AKer
  • Szu_AKer
  • 2016-10-13 21:27
  • 451
    个人资料
    • 访问:1018619次
    • 积分:11171
    • 等级:
    • 排名:第1702名
    • 原创:192篇
    • 转载:139篇
    • 译文:0篇
    • 评论:239条
    关于我
    你的鼠标里,有老鼠喜欢的食物
    博客专栏
    最新评论
    有问题,联系我