內存泄漏也稱作“存儲滲漏”,用動態存儲分配函數動態開闢的空間,在使用完畢後未釋放,結果導致一直佔據該內存單元,直到程序退出,如果在程序退出前達到了系統所分配的最大內存限度時,則會觸發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);
}
}