腾讯Bugly特约作者: 姚潮生
最原始的内存走漏测试
重复屡次操纵症结的可疑的途径,从内存监控东西中视察内存曲线,是不是存在不停上升的趋向且不会在顺序返回时显著回落。
这类体式格局能够发明最基本,也是最显著的内存走漏题目,对用户代价最大,操纵难度小,性价比极高。
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举行题目定位的有用手腕。
Dump出内存走漏当时的内存镜像hprof,剖析疑心走漏的类:
剖析持有此类对象援用的外部对象
剖析这些持有援用的对象的GC途径
逐一剖析每一个对象的GC途径是不是一般
从这个途径能够看出是一个antiRadiationUtil东西类对象持有了MainActivity的援用致使MainActivity没法开释。此时就要进入代码剖析此时antiRadiationUtil的援用持有是不是合理(假如antiRadiationUtil持有了MainActivity的context致使节目退出后MainActivity没法烧毁,那平常都属于内存走漏了)。
2.3 MAT对照操纵前后的hprof来定位内存走漏的根因地点。
为查找内存走漏,一般须要两个 Dump效果作对照,翻开 Navigator History面板,将两个表的 Histogram效果都添加到 Compare Basket中去
第一个HPROF 文件(usingFile > Open Heap Dump ).
翻开Histogram view.
在NavigationHistory view里 (假如看不到就从Window >show view>MAT- Navigation History ), 右击histogram然后挑选Add to Compare Basket .
翻开第二个HPROF 文件然后重做步骤2和3.
切换到Compare Basket view, 然后点击Compare the Results (视图右上角的赤色”!”图标)。
剖析对照效果
能够看出两个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页面等,务求在技术上能带给用户最顺滑的产物体验。
接下来简朴引见下这个东西的推断中心。依据虚援用监控到的内存状况,须要经由过程多种战略来推断是不是存在内存走漏。
最简朴的体式格局就是直接在到场监控时就为该范例设定最大存在个数,举个例子,各个DAO对象理论上只能存在最多一个,因而一旦涌现两个雷同的DAO,那平常都是走漏了;
第二种状况是在页面退出顺序退出时,检索gc后没法开释的对象列表,这些对象范例也会成为内存走漏的疑心对象;
末了一种状况比较复杂,基本道理是依据汗青操纵推断对象数目的增进幅度。依据对象的增进经由过程最小二乘法拟合出该对象范例的增进速度,假如凌驾经验值则会列入疑似走漏的对象列表。
3.3 UIAutomator完成重复操纵的自动化
末了一步就很简朴了。这么多重复的UI操纵,让人工来点就太糟蹋人力了。我们运用UIAutomator来举行自动化操纵测试。
现在手机管家的逐日自动化测试已掩盖各个功用的主途径,并经由过程配置文件的体式格局来天真驱动用例的增编削查,最大限制保证了跟着版本推移用例的复用代价。
至此手机管家的内存走漏测试计划引见终了,也迎接各路牛人交换沟通更多更强的内存走漏东西盒计划!
Bugly 是腾讯内部产物质量监控平台的外发版本,其重要功用是App宣布今后,对用户侧发作的Crash以及卡顿征象举行监控并上报,让开辟同砚能够第一时间相识到App的质量状况,及机遇型修正。现在腾讯内部一切的产物,均在运用其举行线上产物的崩溃监控。