LeakCanary内存泄露监控

内存泄漏问题的排查有很多种方法, 比如说,Android Studio 自带的 Profile 工具、MAT(Memory Analyzer Tool)、以及LeakCanary。 选择 LeakCanary 作为首选的内存泄漏检测工具主要是因为它能实时检测泄漏并以非常直观的调用链方式展示内存泄漏的原因。

1.在build.gradle的中添加依赖包

dependencies {
//leakcanary
debugImplementation ‘com.squareup.leakcanary:leakcanary-android:1.6.3’
releaseImplementation ‘com.squareup.leakcanary:leakcanary-android-no-op:1.6.3’
debugImplementation ‘com.squareup.leakcanary:leakcanary-support-fragment:1.6.3’
}

2、在gradle.properties添加

android.useAndroidX=true
android.enableJetifier=true
3、创建一个LeakCanaryApplication用于监听内存泄露

package com.cvte.auto.androidtesting;

import android.app.Application;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;

public class LeakCanaryApplication extends Application {
private static RefWatcher sRefWatcher;
@Override
public void onCreate() {
super.onCreate();
sRefWatcher = LeakCanary.install(this);
}
public static RefWatcher getRefWatcher() {
return sRefWatcher;
}
}
4、在被测应用的onCreate下直接调用内存泄露监听LeakCanaryApplication.getRefWatcher().watch(this)

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LeakCanaryApplication.getRefWatcher().watch(this);
}
}
5、还有一种方法,直接在被测应用下调用LeakCanary.install(this);

@Override
public void onCreate() {
super.onCreate();
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}
LeakCanary.install(this);
}

6、最简单的方法,使用最新的依赖包,无需写入上述代码https://square.github.io/leakcanary/getting_started/,但只能监控到onCreate()之后的的代码

dependencies {
// debugImplementation because LeakCanary should only run in debug builds.
debugImplementation ‘com.squareup.leakcanary:leakcanary-android:2.7’
}
通过logacat可以查看到是否有开启Leakcanary,内存监控

7、内存泄露的结果将在设备中的通知栏显现,点击查看即可,可以看到以链的方式展现内存泄露,点击+可以查看详细log

这里为了方便演示使用LeakCanary获取和解决内存泄漏的问题,我们先写一个内存泄漏的场景,我们知道最常见的内存泄漏是单列模式使用Activity的Context场景,所以我们也用单列模式来演示

public class Singleton {
private static Singleton singleton;
private Context context;
private Singleton(Context context) {
this.context = context;
}

public static Singleton newInstance(Context context) {
    if (singleton == null) {
        synchronized (Singleton.class) {
            if (singleton == null){//双重检查锁定
                singleton = new Singleton(context);
            }
        }
    }
    return singleton;
}

}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LeakCanaryApplication.getRefWatcher().watch(this);
setContentView(R.layout.activity_main);
Singleton singleton = Singleton.newInstance(this);
}
}

从测试结果可以可以看到问题定位到LinearLayout.mContext,符合预期分析

8、总结:对于安卓项目,需要将上述配置添加到被测应用的源码中,达到源码级别的内存泄露监听。

9、策略:先使用AS中自带的性能分析工具的Profiler进行内存实时监测,找出内存有可能出现内存泄露的的场景,Profiler截取内存有上升趋势的部分并保存为hprof进行分析,另外再使用Leakcanary,复现可能的内存泄露场景,查看设备log,定位内存泄露。

Profiler工具使用参考08.性能分析器的简单使用

你可能感兴趣的:(android)