美文网首页
Android 内存检测工具介绍

Android 内存检测工具介绍

作者: 闫回 | 来源:发表于2020-11-05 15:27 被阅读0次
    1.内存抖动

    短时间内有大量对象创建销毁,它伴随着频繁的GC,比较典型的就是字符串拼接造成的内存抖动

    示例.png

    内存抖动会产生很多的内存碎片,造成内存不连续,在申请内存的时候就有可能造成OOM

    CMS垃圾回收器老年代标记-清除算法:内存碎片.png
    android内存检测工具有androidStudio自带的Memory Profiler和mat,我们先看Memory Profiler
    ,这个工具官网介绍的十分详细https://developer.android.google.cn/studio/profile/memory-profiler,这里我会介绍这个工具的具体使用,
    要打开 Memory Profiler,请按以下步骤操作:
    1. 依次点击 View > Tool Windows > Profiler(您也可以点击工具栏中的 Profile 图标

      image

      )。

    2. 从 Android Profiler 工具栏中选择要分析的设备和应用进程。如果您已通过 USB 连接设备但系统未列出该设备,请确保您已启用 USB 调试

    3. 点击 MEMORY 时间轴上的任意位置以打开 Memory Profiler。

      截屏2020-11-04 下午2.09.11.png
      这是我的一个实例代码,我们在分析的时候一定要点击用于强制执行垃圾回收事件的按钮。
      我们是可以看到这是一个斜坡,说明内存是逐渐增大,这时我们的并没有启动新的页面,当然我们不能只用眼睛去看,还要看具体的数据, 截屏2020-11-04 下午2.14.26.png
      这里的Total是47.4M
      截屏2020-11-04 下午2.14.39.png
      这时就变成了47.6M,说明内存的确在逐渐变大,这时没有出现锯齿是因为内存没有达到需要GC的点,但这时并不能代表它没有内存抖动。
      这时候我们截取一段进行观察
      截屏7.png
      我们可以在右下角可以看到onDraw方法里面的126行
      截屏08.png
      可以看到我们在自定义View里面的onDraw方法里面进行创建对象,我们知道onDraw方法会很有可能多次调用的,
      同样我们发现了同样的问题 截屏24.png
      84行找到是Paint在onDraw里面进行创建
      截屏56.png
      我们再来看一下91行
      截屏07.png
      截屏58.png
      还有一个String的问题
      截屏42.png
      上面就是我们用profile找到的一些问题,现在我们进行修改一下上面的问题。
      把path和paint提取到外面,colors是个数组,使用属性动画去改变
      截屏06.png
      截屏22.png
      现在我们重新使用profile检测一下
      截屏.png
      emm,至此,memory profile工具的使用就先介绍到这里。
    • 预防抖动
      避免在循环中创建对象
      避免在频繁调用的方法中创建对象,如View的onDraw方法
      允许复用的情况下,使用对象池进行缓存,如Handler的Message单链表(obtain)
    2.内存泄漏

    程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费。
    长生命周期对象持有短生命周期对象的强引用,从而导致短生命周期对象无法被回收。

    • 可达性分析法

      通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,搜索所有的引用链,当一个对象到GC Roots没有任何引用链(即GC Roots到对象不可达)时,则证明此对象是不可用的 GCRoots.png
      截屏.png

      第二种解决方法


      截屏.png
      下面介绍如何使用mat进行检测
      截屏.png

    我们在使用profile工具后,点击Dump Java heap按钮会生成一个dump文件,我们把这个文件导出到本地某个文件夹,使用命令进行转换
    hprof-conv xxx.hprof converted-dump.hprof,然后新生成的文件就是hprof


    截屏.png

    然后我们打开mat工具,导入hprof文件


    截屏.png
    Histogram列出所有的对象
    我们点击Histogram,然后选择Group by package这样我们就可以找出我们的类 截屏2020-11-04 下午6.05.47.png
    截屏2020-11-04 下午6.06.56.png

    然后我们排除软弱虚引用看看还有哪些引用

    截屏2020-11-04 下午6.10.09.png

    这时我们可以看到context就是secondActivity被IOSStyleLoadingView所持有,这样就没办法进行回收,我们可以看一下代码找一下原因和解决办法


    截屏2020-11-04 下午6.12.09.png

    addUpdateListener默认持有对外部类的强引用
    解决办法


    截屏2020-11-04 下午6.12.19.png
    现在我们再来试下,看看问题有没有解决
    我们重新生成hprof文件并打开 截屏2020-11-04 下午6.20.53.png
    截屏2020-11-04 下午6.21.01.png

    可以看到没有强引用了,说明问题已经解决了。

    内存问题常见场景

    集合类
    当使用集合时,只有添加元素,没有对应的删除元素,如EventBus只有注册没有注销
    静态成员/单例
    作为GC ROOT,持有短生命周期引用(如Activity)导致其短生命周期对象无法释放。
    未关闭/释放资源
    如FileOutputStream未close,一定要在finally里面close
    非静态内部类
    如Handler postDelayed一个匿名Runnable,退出Activity时消息没处理完

    相关文章

      网友评论

          本文标题:Android 内存检测工具介绍

          本文链接:https://www.haomeiwen.com/subject/dvtgvktx.html