Android LeakCanary的使用和原理,安卓开发项目经历

本文详细介绍了Android开发中LeakCanary的使用和原理,包括其如何监听Activity的生命周期,手动调用GC,以及通过ReferenceQueue和WeakReference检测内存泄露。此外,还探讨了SDK初始化过程,以及分析内存泄露的关键步骤。通过对LeakCanary的源码分析,揭示了其内存泄露检测的机制,并提供了相关知识点和源码解读。
摘要由CSDN通过智能技术生成

@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()已经调用过,这俩种都视为“没有必要执行”

Apolication中可通过processName判断是否是任务执行进程

通过processName,来判断进程

public static boolean isInServiceProcess(Context context, Class<? extends Service> serviceClass) {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo;
try {
packageInfo = packageManager.getPackageInfo(context.getPackageName(), GET_SERVICES);
} catch (Exception e) {
CanaryLog.d(e, “Could not get package info for %s”, context.getPackageName());
return false;
}
String mainProcess = packageInfo.applicationInfo.processName;

ComponentName component = new ComponentName(context, serviceClass);
ServiceInfo serviceInfo;
try {
serviceInfo = packageManager.getServiceInfo(component, 0);
} catch (PackageManager.NameNotFoundException ignored) {
// Service is disabled.
return false;
}

if (serviceInfo.processName.equals(mainProcess)) {
CanaryLog.d(“Did not expect service %s to run in main process %s”, serviceClass, mainProcess);
// Technically we are in the service process, but we’re not in the service dedicated process.
return false;
}

int myPid = android.os.Process.myPid();
ActivityManager activityManager =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.RunningAppProcessInfo myProcess = null;
List<ActivityManager.RunningAppProcessInfo> runningProcesses =
activityManager.getRunningAppProcesses();

  • 15
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值