Android内存泄漏01----LeakCanary初步

来源:互联网 发布:上海淘宝拍摄基地 编辑:程序博客网 时间:2024/05/16 13:47

在android开发的过程,特别容易遇到内存泄漏的现象,当内存泄漏到达一定的程度就会造成内存溢出,也就是常说的oom。那么检测内存泄漏就会显得尤为重要,此处以现在比较火的-LeakCanary为例,来检测app中的内存泄漏。

  使用的案例是 “单例模式”中容易出现的内存泄漏。具体分析,见代码:

 出现内存泄露之前代码:

1.LeakCanary的使用:

(1)在as中添加依赖:

debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'同时在AndroidMainfest中添加
<service    android:name="com.squareup.leakcanary.internal.HeapAnalyzerService"    android:enabled="false"    android:process=":leakcanary" /><service    android:name="com.squareup.leakcanary.DisplayLeakService"    android:enabled="false" />

(2)自定义一个Application

public class MyApp extends Application{    public static RefWatcher getRefWatcher(Context context) {        MyApp application = (MyApp) context.getApplicationContext();        return application.refWatcher;    }    private RefWatcher refWatcher;    @Override public void onCreate() {        super.onCreate();        refWatcher = LeakCanary.install(this);    }}

(3)使用 RefWatcher 监控那些本该被回收的对象。以activity为例。用于自动监控调用 Activity.onDestroy() 之后泄露的 activity。

@Overrideprotected void onDestroy() {    super.onDestroy();    RefWatcher refWatcher = MyApp.getRefWatcher(getApplication());    refWatcher.watch(this);}


2.单例模式的构建


package comm.text.tecent.memorytextdemo01;import android.content.Context;/** * Created by Administrator on 2016/11/20. * * 单例模式内存泄漏 */public class AppManager {    public static AppManager instance;    private Context mContext;    public AppManager(Context mContext) {        this.mContext = mContext; //此处易造成内存泄漏(根据.LeakCanary检测的结果发现)    }    public static AppManager getInstance(Context mContext){        if(instance==null){                instance=new AppManager(mContext);        }        return instance;    }}


当运行app之后,点击返回,销毁了Activity

安装app之后会出现两个icon


过一会通知弹弹出提示,点开如下:




上述表明了 静态的AppManager的事例引用了context 而该context引用了activity的context(activity 继承Context),造成内存泄漏。

因为static的AppManager的实例的生命周期和app的周期一样长,但是在使用的时候,调用的context 传入的时activity的context,导致activity即使被销毁了,也不能够即使的被gc及时的回收。


解决办法:

修改单例中context

package comm.text.tecent.memorytextdemo01;import android.content.Context;/** * Created by Administrator on 2016/11/20. * * 单例模式内存泄漏 */public class AppManager {    public static AppManager instance;    private Context mContext;    public AppManager(Context mContext) {//        this.mContext = mContext; //(泄漏)        /**         * 只要修改为mContext.getApplicationContext()ok         * */               this.mContext = mContext.getApplicationContext();     }    public static AppManager getInstance(Context mContext){        if(instance==null){                instance=new AppManager(mContext);        }        return instance;    }}

再次运行,发现并没有出现泄漏的现像,就这样轻松的解决了内存泄漏的问题。

1 0
原创粉丝点击