普通的观测内存泄漏:主动调用runtime.gc,然后看finalized是否被调用

如何观察到所有Activity的onDestory

通过在application中注册registerActivityLifeCycleCallbacks()获取activity的生命周期

通过注册Activity的LifeCycle,监测到activity的onDestroy状态,在这时RefWatcher.watch(activity)

fragment:activity.getFragmentManager.registerFragmentLifeCycleCallbacks

如何判断Activity泄漏了

记录onDestory的时间点

生成一个uuid作为key

把key加入集合,这个集合就是观察名单

创建包装类KeyedWeakRefrence把key和activity放入,这是一个弱引用

弱引用:如果弱引用包裹的对象只在弱引用中被引用,gc时会直接回收

软引用:比弱引用更强一点,在接近oom时才会被回收,但在Android中,只要gc就会被回收

虚引用:get永远为null,参数里有ReferenceQueue,在gc前会把回收的对象添加进这个queue,用来判断对象是否被回收,比finalize可靠

创建excuter执行检测方法

excuter判断当前是否在主线程,如果是Looper.myQueue.addIdleHandler,这个会在主线程空闲时间执行,执行了说明生命周期正常执行完毕

然后切换子线程执行检测方法ensureGone

对弱引用对象的ReferenceQueue进行轮询取出并对比是否有传入的弱引用对象,如果有,说明已经正确的回收了,把key从集合中移除

如果轮询完怀疑名单中还有对象,主动gc,再次进行上一步

Runtime.getRuntime.gc

try{
    Thread.sleep(100)
} catch (InterreptedException e) {
    throw new AssertionError()
}

System.runFinalization()

如果还是不成功把收集heap信息组成HeapDump对象进行分析

如何收集分析内存泄漏信息

如何收集heap信息:Debug.dumpHprofData

开启服务进行处理

如何分析:使用IntentService,从堆中找到弱引用的对象,通过key判断

找到对象的引用路径,通过第三方库:haha

2.0变化

初始化操作没有了,放在了provider里

支持androidx下的fragment

支持rootview和service检测

rootview:

如何获取:引入第三方库Curtains,原理是反射WindowManagerGlobal

如何检测:rootView.addOnAttachStateChangeListener

service:

如何获取:反射ActivityThread替换Handler得到service销毁的消息

在1.0中Looper.myQueue.addIdleHandler的地方改为延迟5s

分析堆内存自己写了没用haha