一、简介
在 Android 开发中,内存分析是一个非常重要的环节,它可以帮助你识别和解决内存泄漏、内存使用过多等问题。以下是一个简单的内存分析示例,展示了如何使用 Android Studio 的内存分析工具(如 Memory Profiler)来检测和解决内存泄漏问题。
假设我们有一个简单的 Android 应用,其中包含一个可能导致内存泄漏的代码片段。我们将通过内存分析工具来检测这个内存泄漏。
例子:静态持有activity引用的分析

或者通过adb命令:adb shell dumpsys meminfo 应用包名,快速进行内存分析查看,观测activities的数量

一、通过Android studio工具生成文件
抓取记录内存片段,那该如何抓取,可以通过Android studio自带的 profile 工具
详细步骤如下:
-
打开Android Studio:启动你的Android Studio并打开你的项目。
-
连接设备:确保你的Android设备通过USB连接到电脑,或者使用Android模拟器。
-
启动应用:在Android Studio中运行你的应用。
-
打开Profiler工具:在Android Studio中,点击右上角的
Profiler标签,或者通过菜单View > Tool Windows > Profiler打开Profiler窗口。 -
选择设备和进程:在Profiler窗口中,选择你连接的设备和正在运行的应用进程。
-
选择Memory Profiler:在Profiler窗口中,点击
Memory标签以打开内存分析工具。 -
启动内存分析:点击
Record按钮(红色圆点)开始记录内存使用情况。 -
执行操作:在应用中执行你怀疑可能导致内存泄漏的操作。
-
停止记录:完成操作后,点击
Stop按钮(红色方块)停止记录。此时,Profiler会生成一个内存快照。 -
查看内存快照:在Memory Profiler中,你可以看到内存使用情况的图表。点击图表中的任意位置,可以查看特定时间点的内存快照。
-
分析堆内存:点击
Dump Java Heap按钮生成堆内存快照。生成的堆内存快照会显示应用在特定时间点的内存分配情况。 -
查找泄漏对象:在堆内存快照中,查找可能的内存泄漏对象。你可以通过以下方法查找泄漏对象:
- Activity/Fragment泄漏:查找未被正确释放的Activity或Fragment实例。
- 大对象泄漏:查找占用大量内存的大对象。
- 引用链分析:点击泄漏对象,查看引用链,找到导致对象无法被垃圾回收的原因。
上面的详细流程在下面几张图中已经详细标注出来,可仔细查看

生成记录片段,进行下载,导出保存
上图4个泄漏,点击步骤后,找到了MemoryLeakActivity,记住该类后续用分析工具的时候,可以去检索他
按步骤,找到泄漏点,但这里可用信息少了点,经验丰富的人可以看出问题所在(sCallBacks),但是分析工具可以更详细,后续会说到

二、下载eclipse memory analyzer工具,注意版本,下载地址:www.eclipse.org/mat/previou…
我下载的这个版本11.0.20201202,当时下载的最新的,打开后提示报错:java版本不兼容,这个自行选择版本去下载

将Android studio 的profile文件生成的hprof文件,使用命令转化,才能被eclipse memory analyzer工具打开: 命令如下:
找到自己的sdk,platform-tools文件夹使用命令
C:\Users\admin\AppData\Local\Android\Sdk\platform-tools> hprof-conv F:\泄漏profile文件分析\memory-20221220T175022.hprof F:\泄漏profile文件分析\hhh.hprof
后面打开你使用上面命令生成的F:\泄漏profile文件分析\hhh.hprof文件,如下图进行分析

步骤如下:打开histogram(直方图),可以查看某个class具体有多少实例。
搜索检测你想要的问题对象类,该问题类,可以从Android studio的profile 文件分析中看出是哪个

搜索MemoryLeakActivity下图显示有三个,这显然有问题,发生了泄漏

如下图右键选择,找到with incoming references--被哪些类所引用,而 with outgoing reference---代表我引用了哪些类,查看强引用相关的

强引用找到后查看如下图:

查看所有引用,因为这里是强引用,所以直接看就行

如下图找到了sCallBacks,被CallBackManager持有,而CallBackManager为静态

总结:使用profile初步观察,然后使用Memory Analyzer工具详细查看,然后结合代码确认泄漏点