android handler内存,Android handler之内存泄露原因揭示
关于handler机制大家可以看前面专题Android面试精选——再聊android Handler机制。今天我们要说的重点是 handler为什么会发生内存泄露?
我们先从源头说起,应用刚启动时,第一个被执行的方法如下:public static void main(String[] args) {//省略若干行......Looper.prepareMainLooper();ActivityThread thread = new ActivityThread();thread.attach(false);if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}Looper.loop();}
可以见到,在主线程中系统为我们创建了Loop,且调用了loop()方法遍历消息队列。
如果大家看过前面的文章,应该知道我们的loop对象是存在ThreadLocal里,首先这个ThreadLocal不清楚的,可以再看下前面的文章。它是一个静态数据结构。所以被存储在方法区。static final ThreadLocal sThreadLocal = new ThreadLocal();
在消息队列,取完消息后,会执行如下代码:public void dispatchMessage(Message msg) {// 优先执行post(new Runnable)if (msg.callback != null) {handleCallback(msg);} else {if (mCallback != null) {if (mCallback.handleMessage(msg)) {return;}}handleMessage(msg);}}
msg.callback 指的是runnable。比如我们执行了下面代码,msg.callback就不会为null:handler.post(new Runnable() {@Overridepublic void run(){}});
如果我们没有post runnable, 默认会走到handleMessage()方法。这是我们应用层开发大家都比较常见的方法了:private Handler handler=new Handler(){@Overridepublic void handleMessage(Message msg){super.handleMessage(msg);}};
整个流程我们分析完了,现在来回头看看到底为什么会出现内存泄露?
由于我们声明了非静态内部类handler,会导致handler持有activity引用
因为handler 调用了 dispatchMessage()方法,导致message又持有了handler的引用
如果在你退出Activity的时候,有一个消息还没有处理的话,那么这时候Activity是没法回收的。根本原因在于:
因为在方法区里面有static final ThreadLocal sThreadLocal持有Loop引用,而Loop持有MessageQueue引用,MessageQueue持有Message引用,Message持有Handler引用,handler持有Activity引用,所以Activity无法回收,造成内存泄露。引用链如下
方法区-> sThreadLocal -> Loop -> MessageQueue -> Message -> Handler-> Activity。
总结下,内存泄露的根本原因:
Java内存泄漏的根本原因是长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是因为长生命周期持有它的引用而导致不能被回收。
如果你在面试过程中能回答到以上内容,恭喜你,你离Offer不远了。
android handler内存,Android handler之内存泄露原因揭示相关推荐
- 【Android -- 学习笔记】Handler 内存泄漏分析及解决
一.介绍 首先,请浏览下面这段 handler 代码: public class SampleActivity extends Activity {private final Handler mLea ...
- android如何避免内存泄露,Android开发中应该避免的内存泄露
一.背景和目的: 目前许多开发人员在Android开发过程中,较少关注实现细节和内存使用,容易会造成内存泄露,导致程序OOM. 本文会通过代码向大家介绍在Android开发过程中常见的内存泄露. 二. ...
- android跨进程读写内存,Android 跨进程内存泄露
内存泄露的检测和修复一直是每个APP的重点和难点,也有很多文章讲述了如何检测和修复.本篇文章 结合最近开发的项目遇到的实例,讲述下Android Binder导致的内存泄露的一个案例. 发现问题 参与 ...
- android oom工具,Android OOM-Heap,MAT工具检测内存泄露
概述 在android的开发中,要时刻主要内存的分配和垃圾回收,因为系统为每一个dalvik虚拟机分配的内存是有限的,在google的G1中,分配的最大堆大小只有16M,后来的机器一般都为24M,实在 ...
- Android APP常见的5类内存泄露及解决方法
Android APP常见的5类内存泄露及解决方法 参考文章: (1)Android APP常见的5类内存泄露及解决方法 (2)https://www.cnblogs.com/genggeng/p/7 ...
- 85、android handler的警告Handler Class Should be Static or Leaks Occur
转载:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1106/1922.html 在使用Handler更新UI的时候,我是这样写 ...
- Android 性能优化之内存泄漏检测以及内存优化(上)
在 Java 中,内存的分配是由程序完成的,而内存的释放则是由 Garbage Collecation(GC) 完成的,Java/Android 程序员不用像 C/C++ 程序员一样手动调用相关函数来 ...
- Android多线程UI更新-Handler
Handler 处理程序允许您发送和处理Message与线程关联的可运行对象MessageQueue.每个 Handler 实例都与单个线程和该线程的消息队列相关联.当你创建一个新的 Handler ...
- Android面试汇总-Android内存和性能优化面试
一.app优化 app优化:(工具:Hierarchy Viewer 分析布局 工具:TraceView 测试分析耗时的) App启动优化 布局优化 响应优化 内存优化 电池使用优化 网络优化 App ...
最新文章
- Geant4采用make和cmake编译运行geant4自带例子的方法
- Nat. Mach. Intell.|从局部解释到全局理解的树模型
- linux命令下怎么保存python_Linux 环境下安装 Python3 的操作方法
- 电脑开两个微信_怎么在电脑上登陆两个微信?
- winsock setsockopt 详解
- Zephir入门 —— 语法篇
- Cisco路由器安全配置命令
- html 上传文件_【实战篇】记一次文件上传漏洞绕过
- SpringBoot_配置-外部配置加载顺序
- Qt连接Myql的那些事,关于QT连接报错driverNoLoad问题
- 国内外知名工业交换机品牌有哪些?
- android 数据库模糊查询语句_单表千万行数据库:LIKE 搜索优化手记
- 基于IDEA搭建JavaWeb入门项目结构(2021版)
- mysql索引实例_mysql索引之十:Mysql 索引案例学习
- java 编写a-z输出,有1-26个数字和a-z字母,用Java多线程实现先输出2和数字再输出2个字...
- java代码调用python导致系统重启_从Java调用Python代码时出现问题(不使用jython)...
- 麻省理工18年春软件构造课程阅读09“避免调试”
- 使用Pycharm打包应用程序
- 余承东说华为OS操作系统最快今秋面市,真的能承受之重吗??
- 79:企业CRM客户系统:登录模块开发(cookie和session以及登录态校验)
热门文章
- 详解图像处理的算术运算与逻辑运算
- 从保证业务不中断,看网关的“前世今生”
- 从源码角度详解Java的Callable接口
- 教你两种数据库覆盖式数据导入方法
- 技术实践丨GaussDB(DWS)运维管理功能“升级”的原理和使用
- 想设计亿万级高并发架构,你要先知道高并发是什么?
- 云图说|SAP技术画册“一点通”
- 谁说微服务是Spring Cloud的独角戏?Service Mesh了解一下?
- 大前端的自动化工厂(5)—— 基于Karma+Mocha+Chai的单元测试和接口测试
- 基于Matlab的跨孔层析成像的最短路径法弯曲射线追踪(一)