最原始的内存泄露测试

重复多次操作关键的可疑的路径,从内存监控工具中观察内存曲线,是否存在不断上升的趋势且不会在程序返回时明显回落。
这种方式可以发现最基本,也是最明显的内存泄露问题,对用户价值最大,操作难度小,性价比极高。

MAT内存分析工具

2.1 MAT分析heap的总内存占用大小来初步判断是否存在泄露
在Devices 中,点击要监控的程序。
点击Devices视图界面中最上方一排图标中的“Update Heap”
点击Heap视图
点击Heap视图中的“Cause GC”按钮
到此为止需检测的进程就可以被监视。
Heap视图中部有一个Type叫做data object,即数据对象,也就是我们的程序中大量存在的类类型的对象。在data object一行中有一列是“Total Size”,其值就是当前进程中所有Java数据对象的内存总量,一般情况下,这个值的大小决定了是否会有内存泄漏。可以这样判断:
进入某应用,不断的操作该应用,同时注意观察data object的Total Size值,正常情况下Total Size值都会稳定在一个有限的范围内,也就是说由于程序中的的代码良好,没有造成对象不被垃圾回收的情况。
所以说虽然我们不断的操作会不断的生成很多对象,而在虚拟机不断的进行GC的过程中,这些对象都被回收了,内存占用量会会落到一个稳定的水平;反之如果代码中存在没有释放对象引用的情况,则data object的Total Size值在每次GC后不会有明显的回落。随着操作次数的增多Total Size的值会越来越大,直到到达一个上限后导致进程被杀掉。
2.2 MAT分析hprof来定位内存泄露的原因所在。
这是出现内存泄露后使用MAT进行问题定位的有效手段。
A)Dump出内存泄露当时的内存镜像hprof,分析怀疑泄露的类:

B)分析持有此类对象引用的外部对象
C)分析这些持有引用的对象的GC路径
D)逐个分析每个对象的GC路径是否正常
从这个路径可以看出是一个antiRadiationUtil工具类对象持有了MainActivity的引用导致MainActivity无法释放。此时就要进入代码分析此时antiRadiationUtil的引用持有是否合理(如果antiRadiationUtil持有了MainActivity的context导致节目退出后MainActivity无法销毁,那一般都属于内存泄露了)。
2.3 MAT对比操作前后的hprof来定位内存泄露的根因所在。
为查找内存泄漏,通常需要两个 Dump结果作对比,打开 Navigator History面板,将两个表的 Histogram结果都添加到 Compare Basket中去
A) 第一个HPROF 文件(usingFile > Open Heap Dump ).
B)打开Histogram view.
C)在NavigationHistory view里 (如果看不到就从Window >show view>MAT- Navigation History ), 右击histogram然后选择Add to Compare Basket .
D)打开第二个HPROF 文件然后重做步骤2和3.
E)切换到Compare Basket view, 然后点击Compare the Results (视图右上角的红色”!”图标)。
F)分析对比结果
可以看出两个hprof的数据对象对比结果。
通过这种方式可以快速定位到操作前后所持有的对象增量,从而进一步定位出当前操作导致内存泄露的具体原因是泄露了什么数据对象。
注意:
如果是用 MAT Eclipse 插件获取的 Dump文件,不需要经过转换则可在MAT中打开,Adt会自动进行转换。
而手机SDk Dump 出的文件要经过转换才能被 MAT识别,Android SDK提供了这个工具 hprof-conv (位于 sdk/tools下)
首先,要通过控制台进入到你的 android sdk tools 目录下执行以下命令:
./hprof-conv xxx-a.hprof xxx-b.hprof
例如 hprof-conv input.hprof out.hprof
此时才能将out.hprof放在eclipse的MAT中打开。

手机管家内存泄露每日监控方案

目前手机管家的内存泄露每日监控会自动运行并输出是否存在疑似泄露的报告邮件,不论泄露对象的大小。这其中涉及的核心技术主要是AspectJ,MLD自研工具(原理是虚引用)和UIAutomator。
3.1 AspectJ插桩监控代码
手机管家目前使用一个ant脚本加入MLD的监控代码,并通过AspectJ的语法实现插桩。
使用AspectJ的原因是可以灵活分离出项目源码与监控代码,通过不同的编译脚本打包出不同用途的安装测试包:如果测试包是经过Aspect插桩了MLD监控代码的话,那么运行完毕后会输出指定格式的日志文件,作为后续分析工作的数据基础。
3.2 MLD实现监控核心逻辑
这是手机管家内的一个工具工程,正式打包不会打入,BVT等每日监控测试包可以打入。打入后可以通过诸如addObject接口(通过反射去检查是否含有该工具并调用)来加入需要监控的检测对象,这个工具会自动在指定时机(如退出管家)去检测该对象是否发生泄漏。
这个内存泄露检测的基本原理是:
虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用必须和引用队列(ReferenceQueue)联合使用(在虚引用函数就必须关联指定)。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,自动把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。
基于以上原理,MLD工具在调用接口addObject加入监控类型时,会为该类型对象增加一个虚引用,注意虚引用并不会影响该对象被正常回收。因此可以在ReferenceQueue引用队列中统计未被回收的监控对象是否超过指定阀值。
利用PhantomReferences(虚引用)和ReferenceQueue(引用队列),当PhantomReferences被加入到相关联的ReferenceQueue时,则视该对象已经或处于垃圾回收器回收阶段了。
MLD监控原理核心
目前手机管家已对大部分类完成内存泄露的监控,包括各种activity,service和view页面等,务求在技术上能带给用户最顺滑的产品体验。
接下来简单介绍下这个工具的判断核心。根据虚引用监控到的内存状态,需要通过多种策略来判断是否存在内存泄露。
(1)最简单的方式就是直接在加入监控时就为该类型设定最大存在个数,举个例子,各个DAO对象理论上只能存在最多一个,因此一旦出现两个相同的DAO,那一般都是泄露了;
(2)第二种情况是在页面退出程序退出时,检索gc后无法释放的对象列表,这些对象类型也会成为内存泄露的怀疑对象;
(3)最后一种情况比较复杂,基本原理是根据历史操作判断对象数量的增长幅度。根据对象的增长通过最小二乘法拟合出该对象类型的增长速度,如果超过经验值则会列入疑似泄露的对象列表。
3.3 UIAutomator完成重复操作的自动化
最后一步就很简单了。这么多反复的UI操作,让人工来点就太浪费人力了。我们使用UIAutomator来进行自动化操作测试。
目前手机管家的每日自动化测试已覆盖各个功能的主路径,并通过配置文件的方式来灵活驱动用例的增删改查,最大限度保证了随着版本推移用例的复用价值。
至此手机管家的内存泄露测试方案介绍完毕,也欢迎各路牛人交流沟通更多更强的内存泄露工具盒方案!

转载于:https://www.cnblogs.com/krislight1105/p/5203288.html

内存泄露从入门到精通三部曲之排查方法篇相关推荐

  1. 内存泄露从入门到精通三部曲之基础知识篇

    一.首先以一个内存泄露实例来开始本节基础概念的内容: 实例1:(单例导致内存对象无法释放而泄露) 可以看出ImageUtil这个工具类是一个单例,并引用了activity的context. 试想这个场 ...

  2. 内存泄露从入门到精通三部曲之常见原因与用户实践

    2019独角兽企业重金招聘Python工程师标准>>> 内存泄露从入门到精通三部曲之常见原因与用户实践 腾讯Bugly特约作者: 姚潮生 常见原因 1.集合类 集合类如果仅仅有添加元 ...

  3. MySQL数据库,从入门到精通:第十四篇——MySQL视图详解

    MySQL数据库,从入门到精通:第十四篇--MySQL视图详解 第 14 篇_视图 1. 常见的数据库对象 2. 视图概述 2. 1 为什么使用视图? 2. 2 视图的理解 3. 创建视图 3. 1 ...

  4. 从入门到精通,看了这篇文章,你离老黑的路就不远了

    关于被入侵 简单说明: 经常有帖子说:"我中xx木马啦,怎么办?"."我的windows有问题,是不是被入侵啦?"等等.通用的做法是查看可疑进程(win98需要 ...

  5. MySQL零基础从入门到精通(进阶SQL优化篇)

    MySQL零基础从入门到精通(进阶SQL优化篇) SQL优化 insert 如果我们需要一次性往数据库表中插入多条记录,可以从以下三个方面进行优化. insert into tb_test value ...

  6. MySQL数据库,从入门到精通:第十二篇——MySQL数据类型详解

    MySQL数据库,从入门到精通:第十二篇--MySQL数据类型详解 第 12 章_MySQL数据类型精讲 1. MySQL中的数据类型 2. 整数类型 2. 1 类型介绍 2. 2 可选属性 2. 2 ...

  7. html从入门到精通前锋,街篮新手攻略 从入门到精通的心得分享终结篇

    街篮攻略在上一期一说到一些基本的实战技巧,如果掌握那些技巧,街篮入门不成问题.本期分享的是基本技巧之外的进阶技巧,例如:角色选择.阵容搭配.天梯技巧.连招技巧等等. (本文为超好玩原创攻略,转载请注明 ...

  8. 网络安全入门教程(超级详细)从零基础入门到精通,看这一篇就够了。

    前言 随着Web技术发展越来越成熟,而非Web服务越来越少的暴露在互联网上,现在互联网安全主要指的是Web安全. 为了自身不"裸奔"在大数据里,渐渐开始学习Web安全,在学习Web ...

  9. 神仙级python入门教程(非常详细),从零基础入门到精通,从看这篇开始!

    一.初聊Python 1.为什么要学习Python? 在学习Python之前,你不要担心自己没基础或"脑子笨",我始终认为,只要你想学并为之努力,就能学好,就能用Python去做很 ...

最新文章

  1. 分享笔趣阁、宜搜等小说免费API接口
  2. python asp.net requests_python3使用requests访问asp页面时出错,返回500
  3. Openfire on Centos7
  4. 查看linux中shell的几种方法汇总
  5. 修改linux系统时间的方法(date命令)
  6. linux下救援模式
  7. 矩阵微分(matrix derivatives)
  8. C语言:对包含10个整数的数组进行如下的操作,从下标为0的元素开始到最后一个元素,依次向前移动一个位置。
  9. c# emnu 获取注释_C#机器学习之判断日报是否合格
  10. 仿王者荣耀HTML示例代码
  11. android 直播推流sdk,大牛直播Android推流端SDK说明
  12. 用计算机绘制工作表,《计算机操作基础Excel练习题答案.doc
  13. 用vbs写九九乘法表
  14. cafebabe.cc/nazo解答笔记
  15. Venmo、Bakkt、MoneyGram、Uphold的前高管加入Roxe全球支付网络
  16. Android真机连接局域网PC服务器的方法
  17. Android数据传输加密(一):Base64转码算法
  18. [Swift通天遁地]一、超级工具-(16)使用JTAppleCalendar制作美观的日历
  19. Horizon 二次开发 - 登陆页面修改
  20. 教你如何睡觉,一定要看!!!

热门文章

  1. 安卓学习 intent
  2. 《黑马程序员》 流程控制(C语言)
  3. iOS 为tableview添加新的cell类
  4. linux网络体系架构
  5. Your CPU supports instructions that this TensorFlow binary was not compiled to use AVX AVX2
  6. C++ 指针基本概念
  7. VC6.0背景颜色更改
  8. WIN7下搭建FTP
  9. 爬虫软件python彻底卸载_Python爬虫实践:如何优雅地删除豆瓣小组的帖子
  10. vue使用echarts图表