内存泄漏
传统意义上的内存泄漏是至忘记手动释放内存,导致未释放的内存不可使用的现象。jvm 的内存泄漏
jvm的内存泄漏指的是我们本不再需要的内存,躲过了垃圾回收的现象。
android中的内存泄漏指的是 短生命周期的对象被长生命周期的对象所持有,导致无法进行垃圾回收的现象。如何判断一个对象不再使用
引用计数法:优点是简单高效,缺点是会有循环引用的问题。
可达性分析:当一个Activity被回收时,会执行 finalize()。可以通过finalize()是否执行判断Activity是否被回收。
手动 gc
Runtime.getRuntime().gc()
GC 回收机制与分代回收策略
https://juejin.cn/post/6891589544161116168
在 Java 中,有以下几种对象可以作为 GC Root:
Java 虚拟机栈(局部变量表)中的引用的对象。
方法区中静态引用指向的对象。
仍处于存活状态中的线程对象。
Native 方法中 JNI 引用的对象。
具体流程
LeakCanary 在注册了一个AndroidLifecyleCallback,在每一个Activity执行完onDestory后对Activity进行监视。监视的核心方法是RefWatcher.watch()。在watch方法中将需要观察的对象进行了包装,创建了一个WeakReference的对象。
将引用检查的任务通过Looper.myQueue().addIdleHandler添加到MessageQueue中,在主线程空闲的时候进行引用检查操作。
具体的检查操作是循环检查弱引用的返回是否为空,以及检查与弱引用相关的队列,如果弱引用被回收了,引用相关的WeakReference就会被加入到队列中。使用这个方式检查内存泄漏。
java四种引用
https://www.cnblogs.com/pascall/p/10281775.html
- 强引用 它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误
String str = "hello"; // 强引用
str = null; // 取消强引用
- 软引用 在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收;只有在内存空间不足时,软引用才会被垃圾回收器回收。
SoftReference<String> softName = new SoftReference<>("haha");
- 弱引用 具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象。
WeakReference<String> weakName = new WeakReference<String>("hello");
WeakReference(T referent, ReferenceQueue<? super T> q)
4.虚引用 如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。它的作用在于判断一个对象是否被正确的垃圾回收了。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);