LeakCanary 检测到内存泄露【精确分析】

本文探讨了一次实际项目中,如何利用LeakCanary检测到的内存泄露问题,特别关注于倒计时逻辑引发的持久引用,揭示了解决步骤和关键代码分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.内存泄露

LeakCanary集成至项目当中监测内存泄露,可以实时检测,比较好用!

2.检测到的问题

当项目中存在内存泄漏问题时,LeakCanary会通过弹窗的形式,通知你检测到的问题。可以打开LeakCanaryapp会出现弹窗中的泄露位置;

在这里插入图片描述
此时在Logcat中也会打印LeakCanary检测到的问题:

在这里插入图片描述
打印的日志代码如下:

    ====================================
    HEAP ANALYSIS RESULT
    ====================================
    1 APPLICATION LEAKS
    
    References underlined with "~~~" are likely causes.
    Learn more at https://squ.re/leaks.
    
    234941 bytes retained by leaking objects
    Signature: 52415049a0113986014314100d10ae85c9ab46ee
    ┬───
    │ GC Root: Input or output parameters in native code
    │
    ├─ android.os.MessageQueue instance
    │    Leaking: NO (MessageQueue#mQuitting is false)
    │    HandlerThread: "main"
    │    ↓ MessageQueue[2]~~~
    ├─ android.os.Message instance
    │    Leaking: UNKNOWN
    │    Retaining 235.1 kB in 3424 objects
    │    Message.what = 1
    │    Message.when = 1717029504 (109 ms after heap dump)
    │    Message.obj = null
    │    Message.callback = null
    │    Message.target = instance @326657336 of android.os.CountDownTimer$1
    │    ↓ Message.target
    │              ~~~~~~
    ├─ android.os.CountDownTimer$1 instance
    │    Leaking: UNKNOWN
    │    Retaining 235.0 kB in 3423 objects
    │    Anonymous subclass of android.os.Handler
    │    ↓ CountDownTimer$1.this$0
    │                       ~~~~~~
    ├─ (此处为你的包名...).CodeLoginActivity$initListener$5$1 instance
    │    Leaking: UNKNOWN
    │    Retaining 235.0 kB in 3422 objects
    │    Anonymous subclass of android.os.CountDownTimer
    │    this$0 instance of (此处为你的包名...).CodeLoginActivity with mDestroyed = true
    │    ↓ CodeLoginActivity$initListener$5$1.this$0
    │                                         ~~~~~~
    ╰→ (此处为你的包名...).CodeLoginActivity instance
    ​     Leaking: YES (ObjectWatcher was watching this because (此处为你的包名...).CodeLoginActivity received
    ​     Activity#onDestroy() callback and Activity#mDestroyed is true)
    ​     Retaining 234.9 kB in 3421 objects
    ​     watchDurationMillis = 5710
    ​     retainedDurationMillis = 702
    ​     mApplication instance of (此处为你的包名...)BaseApplication
    ​     mBase instance of androidx.appcompat.view.ContextThemeWrapper
    ====================================

3.问题分析

从上面的日志中可以看出整了链表,执行的顺序过程,其中Leaking会有三种状态:NO(无问题)、UNKNOWN(可能有问题)、YES(有问题),从上面的链表当中寻找到;

状态:NO(无问题)

    ├─ android.os.MessageQueue instance
    │    Leaking: NO (MessageQueue#mQuitting is false)
    │    HandlerThread: "main"
    │    ↓ MessageQueue[2]

状态:UNKNOWN(可能有问题)

    ├─ android.os.CountDownTimer$1 instance
    │    Leaking: UNKNOWN
    │    Retaining 235.0 kB in 3423 objects
    │    Anonymous subclass of android.os.Handler
    │    ↓ CountDownTimer$1.this$0

状态:YES(有问题)

    ╰→ (此处为你的包名...).CodeLoginActivity instance
    ​     Leaking: YES (ObjectWatcher was watching this because (此处为你的包名...).CodeLoginActivity received
    ​     Activity#onDestroy() callback and Activity#mDestroyed is true)
    ​     Retaining 234.9 kB in 3421 objects
    ​     watchDurationMillis = 5710
    ​     retainedDurationMillis = 702
    ​     mApplication instance of (此处为你的包名...)BaseApplication
    ​     mBase instance of androidx.appcompat.view.ContextThemeWrapper

此处存在问题,然后去代码中找就可以了

4.我的问题

我的问题是在进行获取验证码的时候,设置的倒计时时间为60秒,当很快获取到验证码,登录成功之后,所引用的倒计时TextView还在引用,导致了内存泄露!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂的沙粒

您的鼓励是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值