什么是LeakCanary

LeakCanary是# square公司推出的专为Android设计的内存泄露检测库

如何集成

官方github地址:https://github.com/square/leakcanary

使用步骤很简单,下面简单把官方步骤翻译一下

1,在build.gradle文件中引入依赖
dependencies {  debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.4'  releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'}
2,在Application的onCreate方法中引入
public class ExampleApplication extends Application {  @Override public void onCreate() {    super.onCreate();    if (LeakCanary.isInAnalyzerProcess(this)) {      // 这个线程是专门给LeakCanary做堆内存分析的      // 在这里不要写app初始化代码      return;    }    LeakCanary.install(this);    // 在这里写你app的初始化代码  }}

到目前为止,LeakCanary已经集成到你的项目中
如果APP的Android编译版本>=4.0版本,那么LeakCanary已经可以自动检测内存泄露了
因为4.0之后Application提供了registerActivityLifecycleCallbacks方法,可以给全局的activity生命周期加入回调,至于原因,我们在源码解析篇进行分析

模拟一个内存泄露

一个比较常见的场景:

Handler作为成员变量接受一个匿名内部类的实现,onCreate方法中,发布一个延时任务,60秒后执行
,然后手动关闭Activity

public class MainActivity extends AppCompatActivity {    private static final String TAG = "MainActivity";    Handler handler = new Handler(){        @Override        public void dispatchMessage(Message msg) {            super.dispatchMessage(msg);            //do something        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        handler.sendEmptyMessageDelayed(0,60 * 1000);    }}

然后屏幕会发出一个提示框


image.png

然后再通知栏会收到一条通知,如果是第一次使用,会先请求写入权限,点击,并允许


image.png

然后过一段时间,通知栏会出现新的通知,点进去就是内存泄漏的引用链


image.png image.png

我们看到MessageQueue中的mMessages中的target持有MainActivity的引用,这个target就是我们MainActivity当中的匿名实现的成员变量Handler,从而得知内存泄露的原因

LeakCanary在检测到内存泄露的同时,除了弹出通知,还会将堆内存dump成hprof文件放在我们的应用所属的file文件夹下面(十分钟之内,只会写入一次)

如果我们想要详细的分析,就需要借助MAT工具,来分析hprof文件

hprof文件

image.png

转换成MAT可识别的文件

cd到sdk/tools的路径下,执行命令 hprof-conv hprof路径 输出路径


image.png

得到mat可识别的文件


image.png

MAT

下载地址:http://www.eclipse.org/mat/downloads.php

win版安装之后如下,点击运行MemoryAnalyzer.exe


image.png image.png

点击右上角菜单File - OpenHeapDump - 刚刚转换后的hprof文件

image.png image.png image.png image.png

右键这个条目 —— Path to GC roots —— with all references

image.png image.png

referent是LeakCanary保存的对Activity的引用
this$0就是内部类所自动保留的一个指向所在外部类的引用

很明显是this$0导致了我们内存的泄露,也就是mMessages中的target,也就是Handler

更多相关文章

  1. Android加载png图片时出错
  2. android:configChanges="keyboardHidden|orientation
  3. 继承Application实现Android数据共享
  4. android webview自动播放Video
  5. linux挂载android 根文件系统的过程
  6. 编译Coco2d-x android 程序出现make: *** No rule to make targe
  7. android linux 基础知识总结(1)
  8. Android(安卓)OpenCV使用2_使用OpenCV并进行人脸检测
  9. Android(安卓)– 在Gradle中更改APK文件名

随机推荐

  1. 关于android UI布局自适应
  2. Android(安卓)UI优化之OverDraw
  3. 快速提高Android开发效率的Web工具
  4. 第三部分:Android(安卓)应用程序接口指南-
  5. Android(安卓)Mvp模式详解(Kotlin篇)
  6. Android配置build.gradle的buildTypes动
  7. adb调试工具
  8. Android(安卓)SQLite分析
  9. 【Android游戏开发十四】深入Animation,
  10. android 自定义控件 自定义属性详细介绍