Android内存泄露自动检测神器LeakCanary
经典的面试题: a、怎样在coding过程中避免内存泄露? b、怎样检测内存泄露? 这两个问题我想大部分Android职位面试时都会被问到吧。 怎样避免就不赘述了,网上很多答案。 工具呢,当然也有很多,比如DDMS、MAT等,但是怎样在我们编码过程中植入内存检测代码,让我们程序在开发调试阶段就能发现内存泄露呢?好了,现在该大名鼎鼎的LeakCanary出场了,它是Square公司的一个内存探测开源项目。下面就介绍下怎样使用. 1、配置gradle依赖: [java] view plain copy debugCompile'com.squareup.leakcanary:leakcanary-android:1.3.1' releaseCompile'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' 2、初始化Watcher [java] view plain copy packagecom.micky.leakcanarysamples;; importandroid.app.Application; importcom.squareup.leakcanary.LeakCanary; importcom.squareup.leakcanary.RefWatcher; /** *@ProjectLeakCanaryTest *@Packatecom.micky.leakcanarysamples; *@Description *@AuthorMickyLiu *@Emailmickyliu@126.com *@Date2016-01-0410:32 *@Version1.0 */ publicclassBaseApplicationextendsApplication{ privatestaticBaseApplicationinstance; privateRefWatchermRefWatcher; @Override publicvoidonCreate(){ super.onCreate(); instance=this; mRefWatcher=Constants.DEBUG?LeakCanary.install(this):RefWatcher.DISABLED; } publicstaticBaseApplicationgetInstance(){ returninstance; } publicstaticRefWatchergetRefWatcher(){ returngetInstance().mRefWatcher; } } 3、在Activity或Fragment中添加检测 [java] view plain copy packagecom.micky.leakcanarysamples; importandroid.app.Activity; importandroid.support.v7.app.AppCompatActivity; /** *@ProjectLeakCanaryTest *@Packatecom.micky.leakcanarysamples; *@Description *@AuthorMickyLiu *@Emailmickyliu@126.com *@Date2016-01-0410:39 *@Version1.0 */ publicclassBaseActivityextendsAppCompatActivity{ @Override protectedvoidonDestroy(){ super.onDestroy(); BaseApplication.getRefWatcher().watch(this); } } 4、测试 [java] view plain copy packagecom.micky.leakcanarysamples;; importandroid.os.Bundle; importandroid.os.Handler; /** *@ProjectLeakCanaryTest *@Packatecom.micky.leakcanarysamples; *@Description *@AuthorMickyLiu *@Emailmickyliu@126.com *@Date2016-01-0410:29 *@Version1.0 */ publicclassTestActivityextendsBaseActivity{ privatefinalHandlermHandler=newHandler(); @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); //模拟内存泄露 mHandler.postDelayed(newRunnable(){ @Override publicvoidrun(){ } },3*60*1000); finish(); } } 5、测试结果 a、Toast显示(大概10秒左右显示) b、通知显示 c、桌面自动添加的图表 d、内存泄露列表 e、内存泄露详细 LogCat可以看到日志日下(hprof文件可以用MAT打开进行分析): [html] view plain copy 01-0411:49:41.81512967-13004/com.micky.leakcanarysamplesI/dalvikvm:hprof:dumpingheapstringsto"/storage/emulated/0/Download/leakcanary/suspected_leak_heapdump.hprof". 01-0411:49:42.02012967-13004/com.micky.leakcanarysamplesI/dalvikvm:hprof:heapdumpcompleted(28850KB) 查看自动生成的AndroidManifest文件,LeakCanarySamples/app/build/intermediates/manifests/full/debug/AndroidManifest.xml [html] view plain copy <?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.micky.leakcanarysamples" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="23"/> <!--Tostoretheheapdumpsandleakanalysisresults.--> <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <android:uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/> <application android:name="com.micky.leakcanarysamples.BaseApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name="com.micky.leakcanarysamples.MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activityandroid:name="com.micky.leakcanarysamples.TestActivity"/> <service android:name="com.squareup.leakcanary.internal.HeapAnalyzerService" android:enabled="false" android:process=":leakcanary"/> <service android:name="com.squareup.leakcanary.DisplayLeakService" android:enabled="false"/> <activity android:name="com.squareup.leakcanary.internal.DisplayLeakActivity" android:enabled="false" android:icon="@drawable/__leak_canary_icon" android:label="@string/__leak_canary_display_activity_label" android:taskAffinity="com.squareup.leakcanary" android:theme="@style/__LeakCanary.Base"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest> 如上所示LeakCanary给我们自动添加了两个Service和一个Activity,并添加了对SD卡的读写权限 It 's so simple. 注: 1、如果在Release模式下请使用RefWatcher.DISABLED 2、在Activity或Fragment 的 Destroy方法中添加检测(很好理解,就是判断一个Activity或Fragment想要被销毁的时候,是否还有其他对象持有其引用导致Activity或Fragment不能被回收,从而导致内存泄露) 源码地址:https://github.com/mickyliu945/LeakCanarySample 点击打开链接 本文转自 一点点征服 博客园博客,原文链接http://www.cnblogs.com/ldq2016/p/6636427.html:,如需转载请自行联系原作者