LeakCanary的Activity的监听泄漏流程(代码层粗略梳理),并附加引用优化和引用队列的例子

本文详细解析了LeakCanary的Activity监听泄漏流程,从安装到ReferenceQueue的轮询检查,阐述了如何通过弱引用检测内存泄漏,并附带了一个优化引用和使用引用队列的示例。

LeakCanary的Activity的监听泄漏流程:
LeakCanary.installl()—〉
AndroidRefWatcherBuilder.buildAndInstall()—〉
RefWatcher创建—〉
ActivityRefWatcher.install(context, refWatcher)—〉
ActivityRefWatcher.install#registerActivityLifecycleCallbacks—〉lifecycleCallbacks.onActivityDestroyed#refWatcher.watch(activity)—〉
RefWatcher.watch()(activity指向的weakReference放入ReferenceQueue,Set放入随机key)—〉
RefWatcher.ensureGoneAsync()—〉
RefWatcher.removeWeaklyReachableReferences()—>
ReferenceQueue queue引用队列轮询检查Activity的弱引用(一些等待逻辑)—〉
runGc—〉
再次执行ReferenceQueue检查—〉
queue.poll()一直是null,Set无法remove掉对应key(即activity指向的weakReference没有释放就是内存泄漏)。

下面附加一个熟悉引用优化和引用队列的例子(摘自“姜新星”老师的GC 回收机制与分代回收策略的文章例子):

public class SoftReferenceTest {
    public static class MyBigObject {
        byte[] data = new byte[1024];//1KB
    }

    public static int removedSoftRefs = 0;
    public static int CACHE_INITIAL_CAPACITY = 100 * 1024;//100M
    public static Set<SoftReference<MyBigObject>> cache = new HashSet<>(CACHE_INITIAL_CAPACITY);
    public static ReferenceQueue<MyBigObject> referenceQueue = new ReferenceQueue<>();

    public static void main(String[] args) {
        for (int i = 0; i < CACHE_INITIAL_CAPACITY; i++) {
            MyBigObject obj = new MyBigObject();
            cache.add(new SoftReference<>(obj, referenceQueue));
            clearUselessReferences();
            if (i % 10000 == 0) {
                System.out.println("size of cache : " + cache.size());
            }
        }
        System.out.println("End,removed soft reference = " + removedSoftRefs);
    }

    public static void clearUselessReferences() {
        Reference<? extends MyBigObject> ref = referenceQueue.poll();
        while (ref != null) {
            if (cache.remove(ref)) {
                removedSoftRefs++;
            }
            ref = referenceQueue.poll();
        }
    }
}

注:运行例子时可以设置VM option为-Xms4M -Xmx4M -Xmn2M。

只有了解源码,并从源码的角度分析,才会找到更完美的解决方案。悟已往之不谏,知来者之可追。实迷途其未远,觉今是而昨非。纸上得来终觉浅,绝知此事要躬行,加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值