FSA全栈行动 FSA全栈行动
首页
  • 移动端文章

    • Android
    • iOS
    • Flutter
  • 学习笔记

    • 《Kotlin快速入门进阶》笔记
    • 《Flutter从入门到实战》笔记
    • 《Flutter复习》笔记
前端
后端
  • 学习笔记

    • 《深入浅出设计模式Java版》笔记
  • 逆向
  • 分类
  • 标签
  • 归档
  • LinXunFeng
  • GitLqr

公众号:FSA全栈行动

记录学习过程中的知识
首页
  • 移动端文章

    • Android
    • iOS
    • Flutter
  • 学习笔记

    • 《Kotlin快速入门进阶》笔记
    • 《Flutter从入门到实战》笔记
    • 《Flutter复习》笔记
前端
后端
  • 学习笔记

    • 《深入浅出设计模式Java版》笔记
  • 逆向
  • 分类
  • 标签
  • 归档
  • LinXunFeng
  • GitLqr
  • AndroidUI

  • Android第三方SDK

  • Android混淆

  • Android仓库

  • Android新闻

  • Android系统开发

  • Android源码

  • Android注解AOP

  • Android脚本

  • AndroidTv开发

  • AndroidNDK

  • Android音视频

  • Android热修复

  • Android性能优化

    • 性能优化 - 内存泄漏(1)入门篇
    • 性能优化 - 内存泄漏(2)工具分析篇
      • 一、简述
      • 二、工具分析
        • 1、System Information
        • 2、Analyzer Tasks
        • 3、MemoryAnalyzer(MAT)
      • 三、总结
        • 1、工具方面
        • 2、操作方面
    • 性能优化 - 内存泄漏(3)代码分析篇
    • 解决WebView内存泄漏
    • Android - setVisibility() 失效,竟然是因为内存泄露
  • Android云游戏

  • Android插件化

  • iOSUI

  • iOS工具

  • iOS底层原理与应用

  • iOS组件化

  • iOS音视频

  • iOS疑难杂症

  • iOS之Swift

  • iOS之RxSwift

  • iOS开源项目

  • iOS逆向

  • Flutter开发

  • 移动端
  • Android性能优化
GitLqr
2017-06-30
目录

性能优化 - 内存泄漏(2)工具分析篇

欢迎关注微信公众号:[FSA全栈行动 👋]

# 一、简述

在上一篇《性能优化——内存泄漏(1)入门篇》 (opens new window)中,介绍了内存泄漏的基本概念,并举了一个Demo,结合简单的代码分析,猜测出Demo中存在内存泄漏,并用Android Studio自带的Memory Monitor证明了我们的猜测,但开发中,业务逻辑可能比较复杂,对象引用繁多,难道都要这样去做代码分析吗?肯定不行,程序员的精力有限,且“很懒”(追求效率),我们需要工具来帮助我们进行分析。下面就来看看都有什么神器吧。

# 二、工具分析

# 1、System Information

System Information是Android Studio自带的分析工具,可以通过它来判断APP整体是否存在内存泄漏。

一个不存在内存泄漏的APP,在其退出并执行过GC后,APP中所有的View和Activity都会被销毁,所以,我们可以根据退出后内存中View和Activity的数量来判断这个APP是否存在内存泄漏。操作如下:

以上一篇中的Demo为例: 运行APP-->打开一个Activity-->屏幕旋转-->点返回键(两次)直到到桌面-->执行GC-->System Information-->Memory Usage

通过上述操作,会生成一个txt文本,其中就记录着View和Activity的数量。如下图所示,它们的值都为0(主要看Activities),说明本APP不存在内存泄漏。相反的,只要值不为0,那么APP是存在内存泄漏的。

这种方式只能判断整个APP是否存在内存泄漏,但无法知道哪里有内存泄漏,也无法得知是哪些对象引用造成的内存泄漏。

# 2、Analyzer Tasks

Analyzer Tasks 是Android Studio自带的分析工具,可以帮助我们快速定位内存泄漏,而且使用上 very easy~

打开一个内存快照(.hprof文件),Android Studio的右侧会出现Analyzer Tasks。

打开Analyzer Tasks后,可以发现有2个选项和一个按钮,说明如下图所示,我们需要的就是第一个"Detect Leaked Activities"。

执行任务后,下方的Analysis Results中会得到泄漏的Activity,而且直接定位到了MemoryLeakActivity[0],要上篇中得到的结果一样。

# 3、MemoryAnalyzer(MAT)

这工具,真心觉得有点复杂,但功能比Android Studio自带的Analyzer Tasks要强大的多。

MemoryAnalyzer是基于eclipse开发的,是一个单独的软件,它也是对.hprof文件进行分析,但必须是标准的.hprof文件,可以从Android Studio中导出。

运行MAT,通过File-->Open Dump分别打开刚刚导出的test1.hprof和test2.hprof,选择Leak Suspects Report-->Finish。

分析的方式有两种,一种是单文件分析,一种是多文件分析,我们先进行单文件分析。

# 1)单文件分析

切换到test2.hprof,打开Histogram。

点击Histogram后,会出来一个Histogram标签,会列出APP中所有类的实例个数,感觉跟Android Studio的.hprof查看器差不多,MAT中的Objects相当于AS中查看器的Total Count。

通过包名筛选,找出了我们自己写的代码,Android Studio的话可以通过切换视图来定位。可以发现MemoryLeakActivity的实例有2个,说明它可能存在泄漏,再联系之前在获取快照之前执行过GC,而这个Activity还没有销毁,说明这个Activity应该是泄漏了。好,到这里单文件分析就结束了。

# 2)多文件分析

分别将test1.hprof和test2.hprof的histogram添加到Compare Basket,详细操作如下图所示。

在Compare Basket中会有刚刚添加的两个.hprof,点击红色感叹号进行对比。

出来的Compared Tables列表跟Histogram很像,不过Objects和Shallow Heap标签都是成双成对。

一样,我们只关心我们自己的代码,所以通过Regex进行筛选。通过数据分析,可以知道,在旋转屏幕前后,MemoryLeakActivity的实例由1增加到了2,又因为test2.hprof是在执行了GC后获取的,所以可以判定MemoryLeakActivity在旋转屏幕后,内存泄漏了。

# 3)引用跟踪

通过单文件分析或多文件分析,我们知道MemoryLeakActivity发生了内存泄漏(被别的实例引用导致无法被GC回收),所以回到test2.hporf的Histogram,筛选出MemoryLeakActivity,右击List objects-->with incoming references。

出来的结果有2大块,即对内存中的2个MemoryLeakActivity实例分别被引用的结果进行了分类,可以看到每个MemoryLeakActivity都被好多个对象引用了。

结合上篇中提到的java中几个特殊类,我们知道SoftReference、WeakReference和PhantomReference在GC一般不会造成内存泄漏,所以这些我们可以不管,也说是说,我们可以对它们进行排除。

对两个Activity分别排除软、弱、虚引用后,得到的结果分别如下:

简单分析下就知道了,第一个MemoryLeakActivity实例是泄漏的,引用它的对象就是CommonUtil。

# 三、总结

# 1、工具方面

个人还是比较推荐使用Android Studio集成的System Information和Analyzer Tasks,主要是使用上方便快捷,还很简单,如果你是高手,并且需要有更强大的功能来帮助你检查APP中的内存泄漏的话,建议使用MAT,在网上多找些比较详细的文章看看,本文对MAT的介绍只是冰山一角。

# 2、操作方面

工具仅仅只是帮助我们快速定位APP中的内存泄漏,并不能直接告诉我们哪里有内存泄漏,实际开发中,需要我们去猜测,去思考,要有清晰的思维,想方设法的构思内存泄漏的判定依据。这需要我们自己去摸索,积累一定的经验。最后,在获取内存快照(Dump Java Heap)之前,建议多点几次Initiate GC,等内存稳定成一条线时再获取内存快照。

#性能优化#内存泄漏
性能优化 - 内存泄漏(1)入门篇
性能优化 - 内存泄漏(3)代码分析篇

← 性能优化 - 内存泄漏(1)入门篇 性能优化 - 内存泄漏(3)代码分析篇→

最近更新
01
Flutter - Xcode16 还原编译速度
04-05
02
AI - 免费的 Cursor 平替方案
03-30
03
Android - 2025年安卓真的闭源了吗
03-28
更多文章>
Theme by Vdoing | Copyright © 2020-2025 FSA全栈行动
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×