作家
登录

Android中导致内存泄漏的竟然是它----Dialog

作者: 来源: 2017-06-04 10:18:04 阅读 我要评论

六. 本来是它!—Dialog

注:以下的分析感悟来自Github膳绫擎的一篇文┞仿:《一个内存泄漏激发的血案》

https://github.com/bboyfeiyu/android-tech-frontier/blob/master/issue-25/%E4%B8%80%E4%B8%AA%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F%E5%BC%95%E5%8F%91%E7%9A%84%E8%A1%80%E6%A1%88-Square.md

有兴趣的童鞋请☞☞ 复制链接到浏览器打开 ☜☜,进行具体浏览!

作者发明,局部变量的生命周期在 Dalvik VM 跟 ART/JVM 中有差别。在 DVM 中,假如线程逝世轮回或者壅塞,那么线程栈帧中的局部变量假如没有被置为 null,那么就不会被收受接收。

如下代码应用壅塞队列解释问题:

子线程中调用 loop()逝世轮回,一向地大年夜壅塞队列中掏出一个 MyMessage 对象并且将对象的引用赋值给局部变量 message,一次 while 轮回之后,虚拟机应当停止 while 花括号中的局部变量的生命周期,并且释放对应的堆内存中的 MyMessage 对象。可是,DVM 没有这么做!!

在 VM 中,每一个栈帧都是本地变量的集合,而垃圾收受接收器是保守的:只要存在一个存活的引用,就不会收受接收它。在每次轮回停止后,本地变量不再可拜访,然而本地变量仍持有对 Message 的引用,interpreter/JIT 理论上应当在本地变量弗查拜访时将其引用置为 null,然而它们并没有如许做,引用仍然存活,并且不会被置为 null,使得它不会被收受接收!!

这种场景不就是 Android Handler 消息机制的处理方法么?!

Looper 一向地大年夜壅塞队列 MessageQueue 中掏出下一条消息 Message 并将引用赋给本地变量 msg。一旦一次轮回停止了,msg 没有被置为 null,对应的 Message 对象没有被收受接收,于是就泄漏了。

不过,Message 是自带收受接收机制的,并且任何线程共用,大年夜膳绫擎源码可以看到,每个 Message 被 Handler 处理完之后都邑 recycle(),置空所有的成员变量,并且放到收受吸收藏中。

好了,被 CookieSyncManager 子线程的 Looper 轮过一次的 Message 对象也跟其他人一样,被收受吸结束放在了收受吸收藏中。这个时刻,刚好碰到了 Dialog!!

如上图,MAT 中的引用链中的 AuthDialog$3 指的就是这里的>

这家伙方才好经由过程 obtainMessage()大年夜收受吸收藏中拿到了这个 Message(被 CookieSyncManager 线程的本地变量引用住了),并且Message.obj 变量就是>

Java Local : A local variable. For example, input parameters, or locally created objects of methods that are still in the stack of a thread. Native stack.

然则,这个 Message 依然占据着堆内存,并且被一个“游离”着的子线程局部变量 msg 引用着!!于是有了这条引用链:

Thread(CookieSyncManager) -> Message -> AuthDialog$3(OnDismissListener) -> AuthDialog -> Activity

针对 Android4.3 及以下版本,或者应用 DVM 的 Android 版本

  1. 应用 WebView 的时刻,须要留意确保调用 destroy()
  2. 推敲是否应用 applicationContext()来构建 WebView 实例
  3. 调用 Dialog 设置 OnShowListener、OnDismissListener、OnCancelListener 的时刻,留意内部类是否泄漏 Activity 对象
  4. 尽量不要本身持有 Message 对象.

【编辑推荐】

  1. HTTPS 道理浅析及其在 Android 中的应用
  2. 【拭魅战】Android Data Binding大年夜抵触到爱不释手
  3. Android若何编写基于编译时注解的项目
  4. Android截屏与WebView长图分享经验总结
  5. Android安然防护之旅---应用"反调试"操作的几种筹划解析
【义务编辑:枯木 TEL:(010)68476606】

  推荐阅读

  Java开发中异常处理的最佳实践

4)始终供给关于异常的有意义的完全的信息异常处理是Java 开辟中的一个重要部分。它是关乎每个应用的一个非功能性需求,是为了处理任何缺点状况,比如资本弗查拜访,不法输入,空输入等等>>>详细阅读


本文标题:Android中导致内存泄漏的竟然是它----Dialog

地址:http://www.17bianji.com/lsqh/35540.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)