Android性能优化 -- Memory Monitor工具检测内存泄露
2018-02-02 09:01
513 查看
这里我们通过一个例子来学习Memory Monitor工具的使用。
上面的代码就是一个单例模式内存泄漏的场景,那么这篇博客的目的就是如何把代码中的内存泄漏找出来。
分析上面的代码,我们知道发生泄漏的不是UserManager,而是MainActivity,知道为什么吗?因为UserManager中有一个静态成员instance,其生命周期和应用程序的生命周期是一致的,当退出应用时,才会被销毁;当MainActivity退出时,有可能发生GC,GC时就会回收MainActivity,因为MainActivity的对象(this)被UserManager对象所引用,UserManager本身是不能被干掉的,所有就会发生内存泄漏。
Memory Monitor使用
在Android Studio界面,双击“Shift”键,打开搜索框,输入“Android Monitor”,即可打开Android Monitor界面。
Memory Monitor是Android Monitor中的一种,位于界面中最上面。
水平方向是时间轴,竖直方向是内存的分配情况;
图中深蓝色的区域,表示当前正在使用中的内存总量;浅蓝色或浅灰色区域,表示空闲内存或者叫做未分配内存。
左上角工具栏三个圆圈按钮依次代表:initiate GC、内存快照(Dump Java Heap)、Allocation Tracking。
initiate GC:手动触发GC操作;
Dump Java Heap:获取当前的堆栈信息,生成一个.hprof文件(包名+日期+".hprof"),Android Studio会自动使用HeapViewer打开,一般用于操作之后检测内存泄漏的情况;
Allocation Tracking:内存分配追踪工具,用于追踪一段时间内的内存分配使用情况。能够知道执行某些操作后,有哪些对象被分配空间。
回到我们的程序,多点击几次GC按钮,看一下这个用于的内存使用情况。
可以看到现在已经分配的内存有5.69MB,我把手机旋转一下,再点击GC按钮。
可以看到现在的内存使用量是6.32MB,却明显增加了,这里很关键!!
接下来,我们找一下哪里发生了内存泄漏。
点击Dump Java Heap,生成快照文件com.android.test_2018.02.01_16.14.hprof,Android Studio会自动弹出HPROF Viewer来分析它。
HPROF Viewer查看方式
左上角两个红框,是可选列表,分别是用来选择Heap区域和Class View的展示方式。
Heap类型分为:
App Heap:当前App使用的Heap。
Image Heap:磁盘上当前APP的内存映射拷贝。
Zygote Heap:Zygote进程Heap(每个APP进程都是从Zygote孵化出来的,这部分基本是framework中的通用类的Heap)。
Class List View:类列表方式。
Package Tree View:根据包结构的树状显示。
HPROF Viewer主要分为ABC三大板块
板块A:这个应用中所有类的名字。
版块B:左边类的所有实例。
板块C:在选择B中的实例后,这个实例的引用树。
A板块左上角列名解释
B板块右上角上角列名解释
B板块右上角有个"的按钮, 点击会进入HPROF Analyzer的hprof的分析界面:
在这个界面中可以直接把内存泄露可能的类找出来。
1. 一个Activity应该只有一个实例,但是从A区域来看total count的值为2,heap count的值也为2,说明有一个是多余的。
2. 在B区域中可以看见两个MainActivity的实例,点击一个看他的引用树情况。
3. 在C区域中可以看到MainActivity的实例Context,被UserManager的instance引用了,引用深度为1。
4. 在Analyzer Tasks 区域中,直接告诉你Leaked Activities,MainActivity包含其中。
多方面的证据表明MainActivity发生了内存泄露。
解决方案
Allocation Tracker
Memory Monitor获得内存的动态视图,Heap Viewer显示堆内存中存储了什么,但是Heap Viewer不能显示你的数据具体分配在代码的何处。还有一个功能Allocation Tracker,用来内存分配追踪。
点击图中Allocation Tracking按钮启动追踪,再次点击停止追踪,随后自动生成一个alloc结尾的文件,这个文件就记录了这次追踪到的所有数据,然后会自动打开一个数据面板。
Allocation Tracker查看方式
有两种查看方式,默认是Group by Method方式。
Group by Method:用方法来分类我们的内存分配。
Group by Allocator:用内存分配器来分类我们的内存分配。
从上图可以看出,首先以线程对象分类,Size是内存大小,Count是分配了多少次内存,点击就可以查看到每个线程里所有分配内存的方法。
关于性能优化内存相关的更多了解可参考:
Android内存优化--OOM
Android性能优化 -- 内存管理机制
示例
package com.android.test; import android.content.Context; public class UserManger { public static UserManger instance; private Context mContext; private UserManger(Context context) { mContext = context; } public static UserManger getInstance(Context context) { if (instance == null) { instance = new UserManger(context); } return instance; } }
package com.android.test; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { UserManger mUserManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mUserManager = UserManger.getInstance(this); } }我们在之前的学习中有说过,内存泄漏产生的原因:当一个对象已经不需要再使用了,本该被回收时,但是因为有另外一个对象持有它的引用,从而导致对象不能被回收,这种导致本该被回收的对象不能被回收而停留在堆内存中,就会产生内存泄漏。
上面的代码就是一个单例模式内存泄漏的场景,那么这篇博客的目的就是如何把代码中的内存泄漏找出来。
分析上面的代码,我们知道发生泄漏的不是UserManager,而是MainActivity,知道为什么吗?因为UserManager中有一个静态成员instance,其生命周期和应用程序的生命周期是一致的,当退出应用时,才会被销毁;当MainActivity退出时,有可能发生GC,GC时就会回收MainActivity,因为MainActivity的对象(this)被UserManager对象所引用,UserManager本身是不能被干掉的,所有就会发生内存泄漏。
Memory Monitor
Android Studio自导的Memory Monitor可以方便的观察堆内存的分配情况,并且可以粗略的观察有没有发生Memory Leak。Memory Monitor使用
在Android Studio界面,双击“Shift”键,打开搜索框,输入“Android Monitor”,即可打开Android Monitor界面。Memory Monitor是Android Monitor中的一种,位于界面中最上面。
水平方向是时间轴,竖直方向是内存的分配情况;
图中深蓝色的区域,表示当前正在使用中的内存总量;浅蓝色或浅灰色区域,表示空闲内存或者叫做未分配内存。
左上角工具栏三个圆圈按钮依次代表:initiate GC、内存快照(Dump Java Heap)、Allocation Tracking。
initiate GC:手动触发GC操作;
Dump Java Heap:获取当前的堆栈信息,生成一个.hprof文件(包名+日期+".hprof"),Android Studio会自动使用HeapViewer打开,一般用于操作之后检测内存泄漏的情况;
Allocation Tracking:内存分配追踪工具,用于追踪一段时间内的内存分配使用情况。能够知道执行某些操作后,有哪些对象被分配空间。
回到我们的程序,多点击几次GC按钮,看一下这个用于的内存使用情况。
可以看到现在已经分配的内存有5.69MB,我把手机旋转一下,再点击GC按钮。
可以看到现在的内存使用量是6.32MB,却明显增加了,这里很关键!!
接下来,我们找一下哪里发生了内存泄漏。
点击Dump Java Heap,生成快照文件com.android.test_2018.02.01_16.14.hprof,Android Studio会自动弹出HPROF Viewer来分析它。
HPROF Viewer使用
下面引用网络一张图片,介绍下HPROF Viewer使用。HPROF Viewer查看方式
左上角两个红框,是可选列表,分别是用来选择Heap区域和Class View的展示方式。
Heap类型分为:
App Heap:当前App使用的Heap。
Image Heap:磁盘上当前APP的内存映射拷贝。
Zygote Heap:Zygote进程Heap(每个APP进程都是从Zygote孵化出来的,这部分基本是framework中的通用类的Heap)。
Class List View:类列表方式。
Package Tree View:根据包结构的树状显示。
HPROF Viewer主要分为ABC三大板块
板块A:这个应用中所有类的名字。
版块B:左边类的所有实例。
板块C:在选择B中的实例后,这个实例的引用树。
A板块左上角列名解释
B板块右上角上角列名解释
列名 | 解释 |
---|---|
Instance | 该类的实例 |
Depth | 深度, 从任一GC Root点到该实例的最短跳数 |
Dominating Size | 该实例可支配的内存大小 |
在这个界面中可以直接把内存泄露可能的类找出来。
1. 一个Activity应该只有一个实例,但是从A区域来看total count的值为2,heap count的值也为2,说明有一个是多余的。
2. 在B区域中可以看见两个MainActivity的实例,点击一个看他的引用树情况。
3. 在C区域中可以看到MainActivity的实例Context,被UserManager的instance引用了,引用深度为1。
4. 在Analyzer Tasks 区域中,直接告诉你Leaked Activities,MainActivity包含其中。
多方面的证据表明MainActivity发生了内存泄露。
解决方案
public class UserManger { public static UserManger instance; private Context mContext; private UserManger(Context context) { mContext = context; } public static UserManger getInstance(Context context) { if (instance == null) { if (context != null) { instance = new UserManger(context.getApplicationContext()); } } return instance; } }不要用Activity的Context,因为Activity随时可能被回收,我们可以使用Application的Context,Application的Context的生命周期是整个应用。
Allocation Tracker
Memory Monitor获得内存的动态视图,Heap Viewer显示堆内存中存储了什么,但是Heap Viewer不能显示你的数据具体分配在代码的何处。还有一个功能Allocation Tracker,用来内存分配追踪。点击图中Allocation Tracking按钮启动追踪,再次点击停止追踪,随后自动生成一个alloc结尾的文件,这个文件就记录了这次追踪到的所有数据,然后会自动打开一个数据面板。
Allocation Tracker查看方式
有两种查看方式,默认是Group by Method方式。
Group by Method:用方法来分类我们的内存分配。
Group by Allocator:用内存分配器来分类我们的内存分配。
从上图可以看出,首先以线程对象分类,Size是内存大小,Count是分配了多少次内存,点击就可以查看到每个线程里所有分配内存的方法。
关于性能优化内存相关的更多了解可参考:
Android内存优化--OOM
Android性能优化 -- 内存管理机制
相关文章推荐
- 性能优化:使用新版Android Studio检测内存泄露和性能
- 性能优化工具2——MemoryAnalyzer(MAT)内存泄露的简单检测
- Android内存优化7 内存检测工具1 Memory Monitor检测内存泄露
- 几个ajax js性能优化和内存泄露问题及检测分析工具
- 几个ajax js性能优化和内存泄露问题及检测分析工具
- Android 内存泄露总结(附内存检测工具)
- Android 性能优化之内存泄漏的检测与修复
- Android 性能优化之使用MAT分析内存泄露问题
- Android 性能优化之使用MAT分析内存泄露问题
- Android 性能优化之使用MAT分析内存泄露问题
- Android性能优化之使用MAT分析内存泄露问题
- Android 性能优化之使用MAT分析内存泄露问题
- Android 性能优化之内存泄漏的检测与修复
- 使用新版Android Studio检测内存泄露和性能
- 为什么要使用内存泄露工具、性能检测工具
- Android 性能优化之使用MAT分析内存泄露问题
- Android 性能优化之使用MAT分析内存泄露问题
- 使用新版Android Studio检测内存泄露和性能
- 使用新版Android Studio检测内存泄露和性能
- Android性能优化(三)——Handler使用不当引起的内存泄露