Android LeakCanary的使用和原理(1)

LeakCanary提供了一种很方便的方式,让我们在开发阶段测试内存泄露,我们不需要自己根据内存块来分析内存泄露的原因,我们只需要在项目中集成他,然后他就会帮我们检测内存泄露,并给出内存泄露的引用链

集成

  • 在gradle中添加依赖,这种不区分debug和release

implementation ‘com.squareup.leakcanary:leakcanary-android:1.5.1’

  • 重写Application

public class App extends Application {

private RefWatcher mRefWatcher;

@Override
public void onCreate() {
super.onCreate();

if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}

mRefWatcher = LeakCanary.install(this);

}

public static RefWatcher getRefWatcher(Context context) {
App application = (App) context.getApplicationContext();
return application.mRefWatcher;
}
}

  • 比如我们在Activity中制造Handler发延迟消息的内存泄露

public class ActivityOne extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);

new Handler().postDelayed(new Runnable() {
@Override
public void run() {

}
}, 100000);
}

@Override
protected void onDestroy() {
super.onDestroy();
}
}

  • 然后我们打开这个activity然后再关闭,桌面就会出现一个leaks的图标,然后我们打开它

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这就是基本使用,其实这种形式只能监视Activity的内存泄露,至于为什么只能监视Activity的内存泄露我们下面再分析,如果想要监视其他的内存泄露怎么办,比如要监视Fragment的内存泄露,可以这样写,主动监视想要监视的对象

public abstract class BaseFragment extends Fragment {

@Override public void onDestroy() {
super.onDestroy();
RefWatcher refWatcher = App.getRefWatcher(getActivity());
refWatcher.watch(this);
}
}

原理概述

通过监听Activity的onDestory,手动调用GC,然后通过ReferenceQueue+WeakReference,来判断Activity对象是否被回收,然后结合dump Heap的hpof文件,通过Haha开源库分析泄露的位置

主要的知识点

注册Activity的生命周期的监听器

通过Application.registerActivityLifecycleCallbacks()方法注册Activity的生命周期的监听器,每一个Actvity的生命周期都会回调到这个ActivityLifecycleCallbacks上,如果一个Activity走到了onDestory,那么就意味着他就不再存在,然后检测这个Activity是否是真的被销毁

通过ReferenceQueue+WeakReference,来判断对象是否被回收

WeakReference创建时,可以传入一个ReferenceQueue对象,假如WeakReference中引用对象被回收,那么就会把WeakReference对象添加到ReferenceQueue中,可以通过ReferenceQueue中是否为空来判断,被引用对象是否被回收

详细介绍推荐博客:www.jianshu.com/p/964fbc301…

MessageQueue中加入一个IdleHandler来得到主线程空闲回调

详细介绍请看Android Handler 源码解析

手动调用GC后还调用了System.runFinalization();,这个是强制调用已失去引用对象的finalize方法

在可达性算法中,不可达对象,也不是非死不可,这时他们处于“缓刑”阶段,要宣告一个对象真正死亡需要至少俩个标记阶段, 如果发现对象没有引用链,则会进行第一次标记,并进行一次筛选,筛选的条件是此对象是否有必要进行finalize()方法,当对象没有覆盖finalize(),或者finalize()已经调用过,这俩种都视为“没有必要执

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值