Android性能优化-内存泄漏(下)
来源:互联网 发布:神圣罗马帝国 知乎 编辑:程序博客网 时间:2024/05/22 11:58
如何进行内存泄漏的分析
使用Android Studio Monitors
AndroidMonitors是Android Studio自带的功能,我们可以通过里面的Memory模块来进行内存泄漏的分析,平时开发我们也可以通过该模块来观察内存的抖动情况。
这里我们首先知道,标注1是进行GC的操作,标注2是进行Dump操作,也就是可以生成我们瞬时的堆内存快照,我们主要也是通过分析堆内存的快照来进行内存泄漏分析。
一般我们先进行几次gc操作,待内存平稳后,执行dump操作。会生成一个phrof的内存快照
此时我们可以看到几个面板:
- ClassName:堆内存中存在的类
- Instaance:类存在的实例
- ReferenceTree:持有该类的引用
几个属性的含义:
- Depth:引用的层级
- Shallow Size:对象的大小(Byte)
- Dominating Size:释放该对象能节省的堆内存(Byte)
将快照转换为Mat能够导入的格式
在as的captures中可以右键选择export to standard .hprof 将快照转换为mat能够带入的文件格式
使用MAT
MAT是一款功能更强大的内存泄漏分析工具,在实际的内存分析中,我们可以结合Monitors进行内存泄漏分析。
下载地址http://www.eclipse.org/mat/
导入快照后,我们可以通过Histogram查看内存快照
在Histogram中,我们可以通过筛选过滤出我们项目中的包和类,这个操作实际中很有用。
选中具体的对象后,右键list objects--with incoming references可以查看对改对象持有的应用
我们可以看到,这个时候引用还是非常的,我们需要过滤一些无用的软引用之类的。通过右键-megre shortest path to GC roots-exclude all phantom/sofe/weak etc.refrences进行过滤,这个时候基本就能查出我们自己写的代码的引用
另外Mat还支持2个快照进行比对,这个功能也是非常有用的。
我们可以在Navigation History中选择 Histogram,然后右键选择Add to compare basket加入比较选项,将2个快照的Histogram加入后在compare basket栏中点击红色感叹号就可以执行快照的比对。
使用leakcanary
Square开源了一个内存泄露自动探测神器——LeakCanary,它是一个Android和Java的内存泄露检测库,可以大幅度减少了开发中遇到的OOM问题。
github https://github.com/square/leakcanary
通过官方的文档介绍,我们可以轻松在项目集成
加入依赖:
dependencies { debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' }
Application 配置:
public class ExampleApplication extends Application { ...... //在自己的Application中添加如下代码public static RefWatcher getRefWatcher(Context context) { ExampleApplication application = (ExampleApplication) context .getApplicationContext(); return application.refWatcher;} //在自己的Application中添加如下代码private RefWatcher refWatcher;@Overridepublic void onCreate() { super.onCreate(); ...... //在自己的Application中添加如下代码 refWatcher = LeakCanary.install(this); ......}.....}
使用 RefWatcher 监控那些本该被回收的对象:
public abstract class BaseFragment extends Fragment { @Override public void onDestroy() { super.onDestroy(); RefWatcher refWatcher = ExampleApplication.getRefWatcher(getActivity()); refWatcher.watch(this); }}
最后如果有内存泄漏,会接收到相应的推送。
这样我们就能在编码的阶段,尽量的避免出现内存泄漏的情况。
如何对自己的项目进行内存泄漏分析
上面说了这么多,怎么来对我们自己的项目进行内存泄漏的分析呢?
一般我们都是在不知道项目中那里有存在内存泄漏的情况下,怎么来查找出那个地方出现了内存泄漏?
这里我们主要检查Activity及Fragment的内存泄漏情况。
使用Memory Usage查看Activity及Fragment的内存泄漏情况,首先先运行自己项目到MainActivity,观察 Menory Usage。
待gc内存稳定后,我们可以执行一些操作,如进入其他的Activity执行其他操作,然后 检测内存的抖动情况及gc稳定后,内存与初始内存的对比。
这里我使用开启不保留活动来模拟MainActivity的异常退出及恢复。继续看Menory Usage。
这个时候,我只有在MainActivity出现过, 理论上应当只有一个MainActivity的实例,这个地方就是一个值得怀疑的内存泄漏的点。这个时候我们就可以通过Mioniter和Mat进行内存分析
这个时候我们可以看到引用的的可怀疑对象,接着我们就进入源码分析。
果然这里有一个单例持有了MainActivity的使用。
分析内存泄漏是一个体力活,我们大概在项目中主要要记住。
使用leakcanary 在编码阶段进行检测
结合内存抖动及Memory Usage 检查Activity及Fragment的的泄漏情况
使用Monitor及Mat进行引用持有分析找出怀疑的对象
分析源代码,找到元凶
- Android性能优化-内存泄漏(下)
- Android性能优化-内存泄漏(上)
- Android性能优化-内存泄漏
- Android性能优化 --- 内存泄漏
- Android 性能优化之内存泄漏检测以及内存优化(下)
- Android内存泄漏与优化(下)
- 性能优化(内存泄漏)
- Android性能优化学习(一)内存泄漏
- Android性能优化学习(三)常见内存泄漏分析
- Android性能优化与内存泄漏分析
- Android性能优化-内存泄漏1
- Android性能优化-内存泄漏2
- Android性能优化: 常见内存泄漏分析
- Android性能优化-内存泄漏(一)
- Android性能优化--防止内存泄漏
- Android性能优化之--内存泄漏
- 性能优化(内存泄漏)
- Android 内存优化OOM 秒变大神 内存泄漏_ 性能优化(四)
- Go获取当前时间
- java面试④数据库部分
- 把apk安装包编译到system.img
- 什么是Git?(看到大牛的解释分享一下)
- 图像的长宽以及灰度、RGB图像的像素原理分布
- Android性能优化-内存泄漏(下)
- Linux基础学习——unit14
- windows系统下Python环境的搭建
- android系统源码中添加app源码(源码部署移植)
- 安卓帧动画的实现
- 实现唯一Launcher
- 每天一道算法题(一) (动态规划算法)背包问题Java实现
- 剑指offer-从尾到头打印链表
- Access denied for user 'Administrator'@'172.16.12.34' (using password: YES)