zoukankan      html  css  js  c++  java
  • 安卓开发中内存问题分析(一)工具篇

    内存泄漏和内存溢出是安卓开发中经常碰到的问题,如何能够快速有效的发现并追踪内存泄漏或者内存溢出的源头,是每个开发者都需要掌握的技巧,今天我给大家带来常见的内存分析工具使用方法,希望对大家今后的开发带来帮助。

    使用Eclipse分析应用内存使用情况

    具体步骤如下:
    1.启动eclipse后,切换到DDMS透视图,并通过Window-ShowView打开Devices视图、Heap视图

    2.连接手机或者模拟器后,在DDMS的Devices视图中将会显示手机设备或模拟器的序列号,以及设备中正在运行的部分进程信息

    3.点击选中想要监测的进程,然后再点击下Update Heap让其自动找到我们运行中应用的进程

    这里写图片描述
    这里写图片描述

    4.点击Heap视图中的“Cause GC”按钮,请求一次GC操作(PS:当内存使用信息第一次显示以后,无须再不断的点击“Cause GC”,Heap视图界面会定时刷新,在对应用的不断的操作过程中就可以看到内存使用的变化)

    这里写图片描述

    5.点击Cause GC之后就可以看到我们应用的内存情况如下图:

    这里写图片描述
    6.具体使用过程中,我们要关注 Heap视图中部有一个Type叫做data object,即数据对象,也就是我们的程序中大量存在的类的对象。在data object一行中有一列是“Total Size”,其值就是当前进程中所有Java数据对象的内存总量,如果大家想要看“Total Size”是分配的具体信息可以点击“data object这一行来查看详细信息,如下图:

    这里写图片描述

    在使用中 “Total Size”这个值的大小决定了是否会有内存泄漏。我们可以通过不断的操作当前应用,同时观察data object的Total Size值的变化情况;正常情况下Total Size值都会稳定在一个有限的范围内,也就是说由于程序中的的代码良好,没有造成对象不被垃圾回收的情况,所以说虽然我们不断的操作会不断的生成很多对象,而在虚拟机不断的进行GC的过程中,这些对象都被回收了,内存占用量会会落到一个稳定的水平;反之如果代码中存在没有释放对象引用的情况,则data object的Total Size值在每次GC后不会有明显的回落,随着操作次数的增多Total Size的值会越来越大,正常情况下,一个虚拟机的进程的内存在64M, 如果内存泄漏会发现 Heap Size 在不断的逼近 64M, 一旦达到这个值时,就会出现内存泄漏退出应用等情况。
    Total Size的值越来越大时,我们按下“Dump HPROF File”按钮,这个时候会提示设置hprof文件的保存路径。保存后,我们可以使用MAT工具来分析是哪些操作造成了内存泄漏。

    使用MAT分析hprof文件

    Eclipse Memory Analyzer(MAT)是著名的跨平台集成开发环境 Eclipse Galileo 版本的 33 个组成项目中之一,它是一个功能丰富的JAVA 堆转储文件分析工具,可以帮助你发现内存漏洞和减少内存消耗。对于大型 JAVA 应用程序来说,再精细的测试也难以堵住所有的漏洞,即便我们在测试阶段进行了大量卓有成效的工作,很多问题还是会在生产环境下暴露出来,并且很难在测试环境中进行重现。JVM 能够记录下问题发生时系统的部分运行状态,并将其存储在堆转储 (Heap Dump) 文件中,从而为我们分析和诊断问题提供了重要的依据。
    官方网站:http://www.eclipse.org/mat/
    从官网中下载最新的MAT工具,打开后如下图:

    这里写图片描述

    废话不多说,MAT的使用步骤如下:
    1.打开 MAT 工具,File–>Open Heap Dump… 选择你刚刚保存的 hprof 文件打开
    此时,会弹出一个错误,如下图所示:

    这里写图片描述

    不要以为是 MAT 工具版本不对,其实是 android 的 hprof 文件在这里需要进行转换一下格式才可以使用 MAT 打开,使用AndrodiSDK/tools/hprof-conv转化hprof文件,
    首先,要通过控制台进入到你的 android sdk tools 目录下
    例如 hprof-conv input.hprof out.hprof
    再使用MAT工具打开转换后的 hprof 文件,就能看到完整的内存使用分析报告了

    这里写图片描述

    2.如下所示是 MAT 分析内存使用的主界面:

    这里写图片描述

    点击上图中的 Reports –>Leak Suspects 则可以进一步看到更详细的内存泄漏疑点

    这里写图片描述

    在其中怀疑的地方,点击 Details 就可以看到具体的内存使用情况了。

    这里写图片描述

    从上图中我们可以看到内存聚集点是一个拥有大量对象的集合,这个对象集合中保存了大量 Person 对象的引用,就是它导致的内存泄露。
    3.另外我们经常会使用Histogram查询

    这里写图片描述

    在某一项上右键打开菜单选择 list objects ->with incoming references 将列出该类的实例,也可以点击表头进行排序,在表的第一行可以输入正则表达式来匹配结果

    这里写图片描述

    4.在选中某一项上右键打开菜单选择 list objects ->with incoming refs 将列出该类的实例:

    这里写图片描述

    在新打开的Tab页面中展示了对象间的引用关系。

    这里写图片描述

    如果想查看某个实例没被释放的原因,可以右健 Path to GC Roots–>exclue all phantom/weak/soft etc. reference :这样变可以快速查看某个对象的 GC Root

    这里写图片描述

    5.有时候为查找内存泄漏,我们通常需要两个Dump结果作对比,这时我们可以打开 Navigator History面板,将两个表的 Histogram结果都添加到 Compare Basket中去 :

    这里写图片描述

    这里写图片描述

    然后点击面板右上角的红色叹号,得到对比结果:

    这里写图片描述

    这里写图片描述

    同时也可以改变对比条件:

    这里写图片描述

    使用AndroidStudio分析应用内存使用情况

    现在开发者普遍使用AndroidStudio进行开发,关于内存使用的分析更加人性化,其内部也默认支持hprof文件的分析,下面带领大家一起学习一下:
    (一) 使用AndroidStudio追踪内存使用状况,打开Android Monitor面板(PS:快捷键Alt+6),点击Memory选项卡

    这里写图片描述

    (二) 使用AndroidStudio分析hprof文件,具体步骤如下:
    1. 在AndroidStudio菜单栏中开Android Device Monitor,如下图:

    这里写图片描述

    2.在Android Device Monitor界面中选在你要分析的应用程序的包名,同时点击Update Heap用来更新统计信息,然后点击Cause GC即可查看当前堆的使用情况,如下图

    这里写图片描述

    3.点击Dump HPROF file,将该应用当前的内存信息保存成hprof文件,存放到你所指定的路径,如下图

    这里写图片描述

    4.在File菜单栏中打开刚才保存的hprof文件(当然为了省事,你也可以直接将hprof文件拖入AndroidStudio中)

    这里写图片描述

    5.在打开的hprof文件中,我们可以很容的找到自己应用程序的包名,打开对应包就可以看到内存使用情况。

    这里写图片描述

    使用LeakCanary分析应用内存使用情况

    这里写图片描述

    LeakCanary 是一个开源的在debug版本中检测内存泄漏的java库。
    GitHub地址:https://github.com/square/leakcanary
    (一)配置说明:

    这里写图片描述

    (二)使用案例:

    这里写图片描述

    创建一个RefWatcher实例,然后给它一个对象让它观察:
    refWatcher.watch(schrodingerCat);
    当检测出泄漏的时候,你会自动得到一个漂亮的泄漏线索:

    • GC ROOT static Docker.container
    • references Box.hiddenCat
    • leaks Cat instance

    然后只需几行代码,LeakCanary就能自动检测Activity的泄漏:

    这里写图片描述

    最终当出现内存不足时,你将看到如下通知界面:

    这里写图片描述

    也就是说,启用LeakCanary之后,可以帮助我们更加方便的发现和修复许多内存问题。

    参考文章:http://www.liaohuqiu.net/cn/posts/leak-canary/

    安卓开发高级技术交流QQ群:108721298 欢迎入群

    微信公众号:mobilesafehome

    (本公众号支持投票)

    Android安全技术大本营

  • 相关阅读:
    数字雨Web安全扫描器V1.2修正版发布
    WebAttak系列教程第二季0x04讲——扫描器之王nmap
    python入门实践111课视频分享
    burpsuite上传截断拿shell
    WebAttak系列教程第二季0x02讲——三次握手
    WebAttak系列教程第二季0x01讲——从零开始
    WebAttak系列教程第二季0x03讲——常见扫描方式简介
    webattack 15视频汇总
    python编程第10讲——包和自定义模块
    在这里记录一个坑爹的问题
  • 原文地址:https://www.cnblogs.com/itrena/p/5938223.html
Copyright © 2011-2022 走看看