移动测试开发 Android 内存泄漏测试工具 LeakCanary

opentest-oper@360.cn · December 24, 2019 · 1136 hits

Android内存泄漏检测利器 LeakCanary
开源工具:https://github.com/square/leakcanary
官方文档:https://square.github.io/leakcanary/
最新版本:2.0

使用方法简介

1.引入依赖库
2.操作应用
3.如果有内存泄漏,通知栏会有消息,点击通知栏可获取到具体内存泄漏信息
4.也可以从手机中拉取hprof文件,使用Android studio的profile工具进行定位分析

操作步骤详解

1.引入依赖库
最新版本的leakcanary不需要插入任何代码,仅仅需要添加build.gradle中加入以下依赖即可:

dependencies {

// debugImplementation 使得仅仅debug版apk才会进行内存泄漏分析 debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0'

}

2.点击通知栏消息获取内存泄漏信息
以下举个例子,APP中在MainActivity跳转到Main2Activity,在Main2Activity中给自定义单例类TestLeak的getInstance方法传入了Main2Activity的context,由于TestLeak中的tl是一个static静态对象,声明周期同Application一样长,当从Main2Activity跳转回MainActivity时,Main2Activity需要被销毁,但是TestLeak中的tl依然持有Main2Activity的context,导致Main2Activity无法被回收,而发生内存泄漏。

public class TestLeak {

private static TestLeak tl;
private Context context;

private TestLeak(Context context) {
this.context = context;
}
//导致了内存泄漏
public static TestLeak getInstance(Context context) {
if (tl == null) {
tl = new TestLeak(context);
// tl = new TestLeak(context.getApplicationContext());
}
return tl;
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void newPage(View view) {
Intent intent = new Intent(this, Main2Activity.class);
startActivity(intent);
}
}
public class Main2Activity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
TestLeak testLeak= TestLeak.getInstance(this);
}
}

操作APP从MainActivity跳转到Main2Activity,再返回MainActivity,查看手机通知栏如下:

点击通知栏后,如下:

由上图可以清晰的看到内存泄漏发生的位置。

3.分析hprof文件定位问题
对于复杂问题可以借助Android studio的profile工具进行定位分析,从上图中的”heap dump file path”拿到hrop文件,打开后如下所示:

上图中 Heap Dump 右边四列的意思分别如下:
Allocations:Java堆中的实例个数
Native Size:native层分配的内存大小
Shallow Size:Java堆中分配实际大小
Retained Size:这个类的所有实例保留的内存总大小
注:在内存泄漏检查的过程中,一般如果Shallow Size和Retained Size都非常小并且相等,都可以认为是已经被回收的对象。因为系统已经不认为它会被用到,并且没有给它保留分配的内存。如果出现上述图中Retained Size远远大于Shallow Size的情况下,就很有可能出现了内存泄漏。

总结

使用leakcanary进行内存泄漏检查,有明显的优势就是对工程中的代码没有任何的侵入,发生内存泄漏后展示的消息可以清楚的定位到问题所在。笔者认为也有一点点缺点那就是内存泄漏发现的时间点相对有些滞后,不能记录问题发生的步骤,复现问题依然困难。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
No Reply at the moment.
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up