如果我们开发的程序,出现内存泄漏,导致程序奔溃,造成用户卸载APP。这样的结果,是我们不想见到的。作为一名向上的程序员,如何避免内存泄漏,这就成为必须要解决的问题。良心企业Square,开源了LeakCanary框架,可以轻松集成,让检测内存泄漏变得十分容易。
什么是内存泄漏?
内存泄漏是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
一、什么是LeakCanary?
LeakCanary 是一个检测内存泄露的开源类库。你可以在 debug 包种轻松检测内存泄露。
LeakCanary源码地址:https://github.com/square/leakcanary
二、LeakCanary源码解析
1.LeakCanary入口
|
|
进入LeakCanary类
refWatcher()返回AndroidRefWatcherBuilder对象,listenerServiceClass、excludedRefs和buildAndInstall皆为
AndroidRefWatcherBuilder的方法。这里我们先看AndroidRefWatcherBuilder中的buildAndInstall的方法
|
|
这里创建了RefWatcher,并把其传给了ActivityRefWatcher。进入ActivityRefWatcher类
创建ActivityRefWatcher类的对象,并且调用了watchActivities()方法,我们继续看
application.registerActivityLifecycleCallbacks(lifecycleCallbacks),设置监听了应用Activity的生命周期,可以监听所有Activity。当Activity调onDestory方法时,都会调 ActivityRefWatcher.this.onActivityDestroyed(activity),我们继续看
2.核心类RefWatcher
这里对watchedReference即Activity对象建立了一个弱应用KeyedWeakReference,并且对KeyedWeakReference加了一个引用队列queue(ReferenceQueue)。当KeyedWeakReference对象可以回收时,会添加到ReferenceQueue中,我们继续
通过watchExecutor开启了一个线程,执行ensureGone。ensureGone方法可以说是LeakCanary框架最最核心的方法,核心原理都在这里。
其中,方法removeWeaklyReachableReferences()是回收弱引用及删除key,方法gone(reference)判断弱引用对象是否被回收。
如代码中的注释,通过多次判断Activity的弱应用是否被回收,判断Activity是否内存泄漏。如泄漏,生成Hprof文件,通过Square的haha开源库分析泄漏引用链,从而将其应用链传给界面展示出来,让开发者知道。
到此,LeakCanary原理分析就告一段落了。如果你还想知道LeakCanary是怎么找到泄漏引用链,并传给界面展示的,你还可以继续分析 heapdumpListener.analyze();入口地方AndroidRefWatcherBuilder中的listenerServiceClass的方法与DisplayLeakService类。
三、总结
通过阅读LeakCanary框架的源码,知LeakCanary框架原理还是比较简单的,主要就是通过Activity弱引用(KeyedWeakReference)是否被回收,来判断是否内存是否泄漏。