leakcanary原理分析

Posted dfqin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leakcanary原理分析相关的知识,希望对你有一定的参考价值。

1、无代码集成原理

目前最新版本是2.8.1,看文档从2.0版本集成时就不需要修改任何代码了,只需要在build.gradle里面添加一行引用:

debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.xxxx'
debugImplementation保证了只在debug环境引入,关于初始化,我们在源码中看到在AndroidManifest.xml中配置了一个provider:

    <provider
        android:name="leakcanary.internal.MainProcessAppWatcherInstaller"
        android:authorities="$applicationId.leakcanary-installer"
        android:enabled="@bool/leak_canary_watcher_auto_install"
        android:exported="false"/>

而在provider中我们可以看到初始化代码:

override fun onCreate(): Boolean 
    val application = context!!.applicationContext as Application
    AppWatcher.manualInstall(application)
    return true

通过相关资料可以知道,provider会在application的onCreate调用之前初始化,所以在provider中对leakcanary初始化,跟手动在application中初始化基本一致。

2、内存泄露监控原理

默认只监控Activity、Fragment、RootView、Service类型的泄露,而这些类型对象有类似与声明周期的节点,知道对象需要释放了。在这个节点,例如Activity的onDestroy(),在这个声明周期后,这个对象就需要释放了,此时对此对象进行监控,看5秒后有没有释放,如果没有释放的话,会触发GC后再判断,如果还没有释放,会认为此对象存在内存泄露,leakcanary会手机泄露信息展示出来。

关于怎么监控一个对象有没有释放,是利用了WeakReference的一个特性,就是创建弱引用时指定一个引用队列(ReferenceQueue),当引用的对象被回收,虚拟机会把此弱引用加入到关联的引用队列中。通过ReferenceQueue中的内容,可以判断对象是否被回收。

3、不同对象监控实现

Activity的监控是通过注册声明周期回调,监听activity销毁时,开始对activity开始监控

private val lifecycleCallbacks =
    object : Application.ActivityLifecycleCallbacks by noOpDelegate() 
      override fun onActivityDestroyed(activity: Activity) 
        reachabilityWatcher.expectWeaklyReachable(
          activity, "$activity::class.java.name received Activity#onDestroy() callback"
        )
      
    

  override fun install() 
    application.registerActivityLifecycleCallbacks(lifecycleCallbacks)
  

Fragment的监控同样是通过注册声明周期回调:

override fun invoke(activity: Activity) 
    val fragmentManager = activity.fragmentManager
    fragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, true)
  

override fun onFragmentDestroyed( fm: FragmentManager, fragment: Fragment) 
      reachabilityWatcher.expectWeaklyReachable(
        fragment, "$fragment::class.java.name received Fragment#onDestroy() callback")
    

View是监控onViewDetachedFromWindow()调用:

rootView.addOnAttachStateChangeListener(object : OnAttachStateChangeListener 

        val watchDetachedView = Runnable 
          reachabilityWatcher.expectWeaklyReachable(
            rootView, "$rootView::class.java.name received View#onDetachedFromWindow() callback"
          )
        

        override fun onViewDetachedFromWindow(v: View) 
          mainHandler.post(watchDetachedView)
        
      )

Android ContentProvider 初始化过程 - 知乎

以上是关于leakcanary原理分析的主要内容,如果未能解决你的问题,请参考以下文章

leakcanary原理分析

leakcanary原理分析

leakcanary原理分析

LeakCanary 2.0原理分析

LeakCanary 2.0原理分析

LeakCanary 内存泄露监测原理研究