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

最原始的内存泄露测试

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


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/375067.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

靶场练习第七天~vulnhub靶场之mrRobot

靶机下载链接: 百度网盘 请输入提取码 提取码: sqv3 一、主机发现 1.用ifconfig查看kali的ip,因为kali和靶机都开启了NAT模式,使用namp -sP 192.168.101.0/24探测靶机ip 二、信息收集 1.使用nmap扫描靶机 使用nmap -A 192.168.101.108 ,查…

JAVA第二次试验

北京电子科技学院(BESTI) 实 验 报 告 课程:Java程序设计 班级:1352 姓名:潘俊洋 学号:20135230 成绩: 指导教师:娄嘉鹏 实验日期:2015.5.4 实验密级&#xff1a…

靶场练习第八天~vulnhub靶场之CH4INRULZ_v1.0.1

一、前期准备 1.靶机下载 链接: 百度网盘 请输入提取码 提取码: z37y 2.用命令ifconfig查看kali 二、信息收集 1.主机发现,使用nmap命令 具体使用方法:nmap -sP 192.168.101.0/24 2.查看该靶机开放了哪些端口 nmap -A 192.168.101.109 直接访问80端…

TImus 1073 Square Country DP

题意&#xff1a;给出一个数n(1<n<60000),这个数可以写成一些数的平方的和&#xff0c; 问对于n&#xff0c;最少可以分成多少个数的平方的和。 比如&#xff1a;n344&#xff0c;则34418*184*42*2&#xff0c;输出3. dp[i]表示i这个数最少可以分成多少个数的平方的和。 …

vulnhub靶机获取不到ip

1.启动靶机&#xff0c;出现如下图所示&#xff0c;按e 2.进入如下图所示时&#xff0c;将ro 替换为 rw signie init/bin/bash 3.按下Ctrl键X键&#xff0c;重启服务进入如下界面 4.查看当前网卡IP信息 ip a 5.编辑网卡配置文件vi /etc/network/interfaces 6.发现网卡名字与刚…

apache整合tomcat部署集群

近日&#xff0c;由于公司项目需要&#xff0c;所以学习了apache整合tomcat以及集群的一些知识。 所以做下笔记日后回顾可以用到。 apache只有处理静态事物的能力&#xff0c; 而tomcat的强项就是处理动态的请求&#xff0c;所以apache和tomcat整合相互取长补短&#xff0c;由a…

靶场练习第九天~vulnhub靶场之dc-1

一、环境搭建 靶场下载链接: 百度网盘 请输入提取码 提取码: ih67 1.查看kali的ip&#xff1a;ifconfig 二、信息收集 1.使用namp命令 主机探测: nmap -sP 192.168.101.0/24 查看靶机开放端口号和服务:nmap -A 192.168.101.111 发现开放80端口,访问一下192.168.101.111 Dru…

靶场练习第十天~vulnhub靶场之dc-2

一、准备工作 靶机下载地址链接: 百度网盘 请输入提取码 提取码: ib86 二、信息收集 1.nmap的信息收集 &#xff08;1&#xff09;使用nmap 192.168.101.0/24&#xff0c;发现靶机地址为192.168.101.115 &#xff08;2&#xff09;对靶机做进一步探测&#xff0c;发现靶机开…

Ubuntu 14.10 创建虚拟网卡实现桥接网络

目标需求&#xff1a;在Ubuntu主机创建一张虚拟网卡&#xff0c;使得搭建在VirtualBox中的其他主机能借助虚拟网卡构建的局域网进行相互间的通讯 步骤一&#xff1a;准备工具包 安装 uml-utilities 以及 bridge-utils sudo apt-get install uml-utilities bridge-utils 步骤二&…

靶场练习第十一天~vulnhub靶场之dc-3

一、准备工作 1.靶场链接: 百度网盘 请输入提取码 提取码: 48d3 2.启动靶场后会遇到如下情况&#xff1a; 2-1具体解决办法如下&#xff1a; 启动成功 3.查看kali的ip&#xff1a;ifconfig 二、信息收集 1.nmap的信息收集 &#xff08;1&#xff09;寻找靶机的ip&#xf…

靶场练习第十二天~vulnhub靶场之dc-4

一、准备工作 1.靶机下载链接 链接: 百度网盘 请输入提取码 提取码: 3hq4 2.用ifconfig查看kali的ip 二、信息收集 1.nmap的信息收集 &#xff08;1&#xff09;主机发现 命令&#xff1a;nmap 192.168.101.0/24 &#xff08;2&#xff09;扫描靶机详细信息 发现主机 192…

靶场练习第十三天~vulnhub靶场之dc-5

一、准备工作 1.靶机环境搭建 下载链接: https://pan.baidu.com/s/1csvuJ_NVCBvVr75KhxyM3Q?pwdxie7 提取码: xie7 2.kali的ip 命令&#xff1a;ifconfig 3.kali和靶机的都设置为NAT模式 二、信息收集 1.nmap的信息收集 &#xff08;1&#xff09;寻找靶机的ip 命令&…

靶场练习第十四天~vulnhub靶场之dc-6

一、准备工作 kali和靶机都选择NAT模式&#xff08;kali与靶机同网段&#xff09; 1.靶场环境 下载链接: 百度网盘 请输入提取码 提取码: bazx 2.kali的ip 命令:ifconfig 3.靶机的ip 扫描靶机ip 命令&#xff1a;sudo arp-scan -l 二、信息收集 1.nmap的信息收集 &#…

最短路径Dijkstra算法和Floyd算法整理、

转载自&#xff1a;http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径—Dijkstra算法和Floyd算法 Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法&#xff0c;用于计算一个节点到其他所有节点的最短路径。主要特点是以…

Java Script 中 ==(Equal) 和 === (Identity Equal) 的区别和比较算法逻辑

判断两个变量是否相等在任何编程语言中都是非常重要的功能。 JavaScript 提供了 和 两种判断两个变量是否相等的运算符&#xff0c;但我们开始学习的时候 JavaScript 的时候&#xff0c;就被一遍又一遍的告知&#xff1a; 要求变量的类型和值均相等&#xff0c;才能返回true…

靶场练习第十五天~vulnhub靶场之dc-7

一、准备工作 kali和靶机都选择NAT模式&#xff08;kali与靶机同网段&#xff09; 1.靶场环境 下载链接:https://download.vulnhub.com/dc/DC-7.zip 2.kali的ip 命令:ifconfig 3.靶机的ip 扫描靶机ip sudo arp-scan -l 二、信息收集 1.nmap的信息收集 &#xff08;1&…

靶场练习第十六天~vulnhub靶场之dc-8

一、准备工作 kali和靶机都选择NAT模式&#xff08;kali与靶机同网段&#xff09; 1.靶场环境 下载链接:https://download.vulnhub.com/dc/DC-8.zip 2.kali的ip 命令:ifconfig 3.靶机的ip 扫描靶机ip sudo arp-scan -l 二、信息收集 1.nmap的信息收集 &#xff08;1&…

【SpringMVC】SpringMVC系列4之@RequestParam 映射请求参数值

4、RequestParam 映射请求参数值 4.1、概述 Spring MVC 通过分析处理方法的签名&#xff0c;将 HTTP 请求信息绑定到处理方法的相应人参中。Spring MVC 对控制器处理方法签名的限制是很宽松的&#xff0c;几乎可以按喜欢的任何方式对方法进行签名。必要时可以对方法及方法入…

Sprint3

进展&#xff1a;今天主要是各自熟悉安卓应用开发平台&#xff0c;设计了图标&#xff0c;没什么实际上的进展。 燃尽图&#xff1a; 团队工作照&#xff1a; 转载于:https://www.cnblogs.com/XJXYJ/p/4495810.html

靶场练习第十七天~vulnhub靶场之dc-9

一、准备工作 kali和靶机都选择NAT模式&#xff08;kali与靶机同网段&#xff09; 1.靶场环境 下载链接:https://download.vulnhub.com/dc/DC-9.zip 2.kali的ip 命令:ifconfig 3.靶机的ip 扫描靶机ip sudo arp-scan -l 二、信息收集 1.nmap的信息收集 &#xff08;1&am…