LeakCanary原理 弱引用与垃圾回收

LeakCanary

LeakCanary 通过 hook Android 的生命周期来自动检测 Activity 和 Fragment 何时被销毁,何时应该被垃圾回收,这些被 destroy 的对象被传递给 ObjectWatcher,ObjectWatcher 持有对它们的弱引用

检测对象类型

  • 已销毁的 Activity 实例
  • 销毁的 Fragment 实例
  • 销毁的 Fragment View 实例
  • 已清除的 ViewModel实例

弱引用与垃圾回收

弱引用(WeakReference)可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收器回收,虚拟机就会把这个弱引用加入到与之关联的引用队列中,我们可以用此特性来检查一个对象是否被垃圾回收器回收成功
LeakCanary原理 弱引用与垃圾回收_第1张图片

强引用

-般的obiect obj= new Object0),就属于强引用。在任何情况下,只有有强引用关联(与根可达)还在,垃圾回收器就永远不会回收掉被引用的对象。

软引用 SoftReference

  • 一些有用但是并非必需,用软引用关联的对象,系统将要发生内存溢出(0uyOfMemory)之前,这些对象就会被回收(如果这次回收后还是没有足够的空间,才会抛出内存溢出)。
    参见代码:
    VM参数-Xms10m-Xmx10m -XX:+PrintGc

例如,一个程序用来处理用户提供的图片。如果将所有图片读入内存,这样虽然可以很快的打开图片,但内存空间使用巨大,一些佳用较少的图片浪费内存空间,需要手动从内存中移除。如果每次打开图片都从磁盘文件中读取到内存再显示出来,虽然内存占用较少,但一些经常使用的图片每次打开都要访问磁盘,代价巨大。这个时候就可以用软引用构建缓存。

弱引用WeakReference

  • 一些有用(程度比软引用更低)但是并非必需,用弱引用关联的对象,只能生存到下一次垃圾回收之前,GC发生时,不管内存够不够,都会被回收。
  • 当一个对象仅仅被WeakReference(弱引用)指向,而没有任何其他strong reference(强引用)指向的时候,如果这时GC运行,那么这个对象就会被回收,不论当前的内存空间是否足够,这个对象都会被回收。
  • 注意:软引用 SoftReference和弱引用 WeakReference,可以用在内存资源紧张的情况下以及创建不是很重要的数据缓存。当系统内存不足的时候,缓存中的内容是可以被释放的。
  • 实际运用(WeakHashap、ThreadLocal)

GC回收后,弱引用不存在代码示例:

fun main(){
    val referenceQueue = ReferenceQueue()
    var obj:Any? = Object()
    val weakReference = WeakReference(obj, referenceQueue)
    println("before GC:${weakReference.get()}")
    obj = null
    System.gc()
    Thread.sleep(1000)
    println("after GC:${weakReference.get()}")
}

虚引用

  • 幽灵引用,最弱(随时会被回收掉)
  • 垃圾回收的时候收到一个通知,就是为了监控垃圾回收器是否正常工作。

你可能感兴趣的:(android,edge,android)