您的位置:首页 > 移动开发 > Android开发

Android内存泄漏检查利器——LeakCanary

2016-09-08 11:39 549 查看

内存泄漏也称作“存储渗漏”,用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元,直到程序退出,如果在程序退出前达到了系统所分配的最大内存限度时,则会触发OOM导致程序崩溃。相信大多开发者对于内存泄漏并不陌生,但是如何去发现内存泄漏、定位内存泄漏以及处理内存泄漏可能就有些生疏了。本篇将介绍如何使用Android内存泄漏检查利器——LeakCanary去发现内存泄漏以及定位到内存泄漏。而在处理内存泄漏上我们需要根据具体情况采取具体的措施。

LeakCanary

LeakCanary是一个Android和Java的内存泄露检测库,可以大幅度减少了开发中遇到的OOM问题

配置LeakCanary

LeakCanary的配置很简单,首先在app中的build.gradle里的dependencies接点下引用

com.squareup.leakcanary:leakcanary-android:1.4-beta2

dependencies {
compile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
}


接着我们需要自己创建Application,并在onCreate方法中初始化它。

public class MainApplication extends Application{

@Override
public void onCreate() {
super.onCreate();
RefWatcher refWatcher = LeakCanary.install(this);
}
}


最后在AndroidManifest配置一下我们创建的Application就行了。

<application
android:allowBackup="true"
android:name=".MainApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
... ...
</application>


编译运行到手机上后的情况如下图所示就算是配置成功了。



这里多出了一个应用——Leaks。现在打开到里面看除了导航栏指明此Leak属于哪个应用的之外,什么东西都没有。这个可以先不管,我们写一段会发生内存泄漏的代码来看看会是什么情况。

这里我们采用最典型的单例引起的Context内存泄漏来做示例。

public class MyInstance {
private Context context;
private static MyInstance mInstance;

public static MyInstance getInstance(Context context) {
if (mInstance == null) {
synchronized (MyInstance.class) {
if (mInstance == null)
mInstance = new MyInstance(context);
}
}
return mInstance;
}

private MyInstance(Context context) {
this.context = context;
}

}


接着我们新建一个Activity,在onCreate中传入自身的context来初始化MyInstance。

public class TestActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
MyInstance.getInstance(this);

}
}


然后在MainActivity中写个按钮点击事件跳转到TestActivity中,再在TestActivity回退到MainActivity。

回退到MainActivity中等待一小会后我们可以看到Leaks发出了通知消息,说明已经检测到出现了内存泄漏的问题。点开通知我们可以看到如下界面:



可以发现是在TestActivity中发生的内存泄漏,原因是MyInstancem的mInstance引用的context为TestAcitivty。现在如果我们打开Leaks,可以发现它已经为我们记录了一条内存泄漏的信息。

因此,我们只需将创建MyInstancem的传入值改成生命周期最长的ApplicationContext后就能解决这个问题了。

在开发中我们在一开始就应该对程序进行内存泄漏检查,以便我们及时发现内存泄漏的问题并更加容易定位到问题代码,采取相应的解决措施。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息