谈谈 LeakCanary 原理 –标准答案

时间:2021-7-3 作者:qvyue
  1. 内存泄漏
    传统意义上的内存泄漏是至忘记手动释放内存,导致未释放的内存不可使用的现象。

  2. jvm 的内存泄漏
    jvm的内存泄漏指的是我们本不再需要的内存,躲过了垃圾回收的现象。
    android中的内存泄漏指的是 短生命周期的对象被长生命周期的对象所持有,导致无法进行垃圾回收的现象。

  3. 如何判断一个对象不再使用
    引用计数法:优点是简单高效,缺点是会有循环引用的问题。
    可达性分析:

  4. 当一个Activity被回收时,会执行 finalize()。可以通过finalize()是否执行判断Activity是否被回收。

  5. 手动 gc Runtime.getRuntime().gc()

  6. GC 回收机制与分代回收策略
    https://juejin.cn/post/6891589544161116168

在 Java 中,有以下几种对象可以作为 GC Root:
Java 虚拟机栈(局部变量表)中的引用的对象。
方法区中静态引用指向的对象。
仍处于存活状态中的线程对象。
Native 方法中 JNI 引用的对象。

具体流程

  1. LeakCanary 在注册了一个AndroidLifecyleCallback,在每一个Activity执行完onDestory后对Activity进行监视。监视的核心方法是RefWatcher.watch()。在watch方法中将需要观察的对象进行了包装,创建了一个WeakReference的对象。

  2. 将引用检查的任务通过Looper.myQueue().addIdleHandler添加到MessageQueue中,在主线程空闲的时候进行引用检查操作。

  3. 具体的检查操作是循环检查弱引用的返回是否为空,以及检查与弱引用相关的队列,如果弱引用被回收了,引用相关的WeakReference就会被加入到队列中。使用这个方式检查内存泄漏。

java四种引用
https://www.cnblogs.com/pascall/p/10281775.html

  1. 强引用 它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误
String str = "hello";    // 强引用
str = null;              // 取消强引用
  1. 软引用 在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收;只有在内存空间不足时,软引用才会被垃圾回收器回收。
SoftReference softName = new  SoftReference("haha");
  1. 弱引用 具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象。
WeakReference weakName = new WeakReference("hello");
WeakReference(T referent, ReferenceQueue super T> q)

4.虚引用 如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。它的作用在于判断一个对象是否被正确的垃圾回收了。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。

ReferenceQueue queue = new ReferenceQueue();
PhantomReference pr = new PhantomReference(new String("hello"), queue);
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。