概念 | 说明 |
什么是内存泄漏? | 在计算机中,由于疏忽或错误造成程序未能释放已经不再使用的内存,叫做内存泄漏。 在Java中,存在一些被分配的对象。
如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。 |
如何检测Activity是泄露的? | 一个Activity如果已经执行了onDestroy(),那么他的生命周期已经结束,不应该被任何对象所引用。在下一次GC回收的时候应该把执行了onDestroy()的Activity回收掉。如果执行了GC依然没有被回收,则判定当前Activity有强引用,已经泄露。 |
如何判断执行了GC? | 支持代码主动触发GC,但是频繁GC对APP的整理运行并不友好,可能会造成卡顿。所以支持配置延迟检测Activity泄露,尽可能的让系统自己触发GC回收,而不是人为主动触发。 在Activity onDestroy后时建立一个WeakReference对一个new Object()的引用,如果这个new Object()被回收则认为触发了GC。 |
如何判断Activity是否被回收? | 使用 WeakReference(T referent, ReferenceQueue<? super T> q)包装Activity,在Activity被垃圾回收器回收后,reference会被放入内部的ReferenceQueue中。 也就是说,从队列ReferenceQueue取出来的所有reference,它们指向的真实对象都已经成功被回收了。 |
什么是内存泄漏兜底? | 一些泄漏的对象的生命周期已经结束,但依然存在着强引用,导致对象没有办法被GC回收。通过代码主动断开泄露对象到GC ROOT的链路,或者释放掉泄露对象的引用对象,让这些泄露对象在下次GC时候可以被回收掉,释放出内存空间,这就是内存泄露兜底。它就像一个自动扫地机器人,不断地帮您在房间清理垃圾。 |
内存泄漏兜底处理哪些对象? |
通过延时处理泄露Activity持有View树的背景图和ImageView的图片,在Activity泄露后把背景图和ImageView的图片置空,防止图片泄露。 当然更激进的可以把RootView的所有子View全都Remove掉,但是业务使用复杂,很有可能在Remove后,依然有对View树的处理,产生空指针异常。 |