记录一次NullPointerException的排查之路

这周工作忙完了,闲来无事,去firebase看一眼,呃有个空指针:

Fatal Exception: java.lang.NullPointerException

Attempt to invoke virtual method 'void ***.verify.AuthDialogCallBack.onDismiss()' on a null object reference

赶紧打开代码敲敲,奇怪啊,照理说不应该出现这个空指针啊。。。。于是俺陷入了深深的思考。。

难道是内存泄漏???

脑子里突然闪出这个想法,凭我多年的经验,如果一些错误,找不到问题所在,很大的可能是内存泄漏导致的,那就查查吧。leakcanary走起~

果然有内存泄漏,可是内存泄漏为什么会导致此处的空指针异常呢?带着问题巡查代码。

原来是我的AuthVerifyDialogFragment实例,因为内存泄漏,导致没有回收掉,而我的AuthDialogCallBack已经回收掉了,所以导致了空指针的发生。

既然找到了问题所在,那就改起来吧。。。哎😔。

那么,问题来了,为什么会有这个内存泄漏的发生呢?

经过。。一番资料查询,原来是因为:

1、某一个 HandlerThread 的 Looper#loop 方法,一直等待 queue#next 方法返回,但是它的 msg 局部变量还引用着上一个循环中已经被放到 Message Pool 中 Message,我们称之为 MessageA。
2、DialogFragment#onActivityCreated 方法中,会调用 Dialog#setOnCancelListener 方法,将自身的引用作为 listener 参数传递给该方法
3、Dialog#setOnCancelListener 方法内部,会尝试从 Message Pool 中获取一个 Message,取出的 Message 刚好是 MessageA,然后将传入的 Listener 实例赋值给 MessageA#obj。
4、外部调用 cancel 的时候,Dialog 内部会将 MessageA 拷贝一份,我们称它为 MessageB,然后将 MessageB 发送到消息队列中。
5、DialogFragment 收到 onDestory 回调之后,LeakCanary 开始监听这个 DialogFragment 是否正常被回收,发现这个实例一直存在,dump 内存,分析引用链,报告内存泄漏问题。

感谢掘金作者:https://juejin.cn/post/6844904191912050702

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值