You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Moosphan, shs8023you, Ronny-dev, 479493023, Cmdone and 40 moreADrunkenLiBai, darrenjh, niexiaoqiang and liushuai42YehFeng and ychong996YehFengMrsunbwzhangzhen92 and Jackie-a
anshuangxinanshuangxin and benteyCodeADrunkenLiBai, pengMaster, anshuangxin, MrDon94, georgekwock and 1 moreanshuangxinanshuangxinanshuangxinanshuangxinanshuangxin
Your this kind of train of thought is incorrect, upstairs consciousness is how to avoid the happening of the problem, your train of thought is to do not have a problem namely, it is not my business.The train of thought decides the way out, big brother, see the gap?
sinduanan, zuoni1018, Seckawijoki, mikilangkilo, jacksinrow and 2 morezuoni1018 and lanzhu1993iamcainiaot, zuoni1018, Mario0o and liangrk
Activity
Ssuiyingsen commentedon Mar 8, 2019
1.自定义的静态handler
2.可以加一个弱引用
3.还有一个主意的就是当你activity被销毁的时候如果还有消息没有发出去 就remove掉吧
4.removecallbacksandmessages去清除Message和Runnable 加null 写在生命周的ondestroy()就行
ADrunkenLiBai commentedon Mar 8, 2019
弱引用会不会出现问题
Ssuiyingsen commentedon Mar 8, 2019
不加弱引用的时候 如果GC不了 那岂不是GG了
ADrunkenLiBai commentedon Mar 8, 2019
现在手机都12G RAM,一个小小的handler就能让他崩溃吗
Ssuiyingsen commentedon Mar 8, 2019
我竟无言以对 流弊流弊
windflowersnowandmoon commentedon Mar 8, 2019
Your this kind of train of thought is incorrect, upstairs consciousness is how to avoid the happening of the problem, your train of thought is to do not have a problem namely, it is not my business.The train of thought decides the way out, big brother, see the gap?
windflowersnowandmoon commentedon Mar 8, 2019
God, can we drink together?
Ssuiyingsen commentedon Mar 8, 2019
Sure
ADrunkenLiBai commentedon Mar 8, 2019
Sure !
FeatherHunter commentedon Mar 12, 2019
使用弱引用是对的,静态内部类也是对的。
问题2:不使用这些方法,Handler直接持有Activity的引用是否一定会导致内存泄漏?
个人写的Handler,且没有耗时操作。没必要保护。
公司项目对于代码规范的话,还是加上保护比较好。避免后续有同事,加上了耗时操作,出现问题。
DaveBoy commentedon Mar 20, 2019
是的,正如楼上所说,其实正常情况下是不会内存泄漏的,除非handler队列等待太久(什么情况会这样呢?anr?延时太久?)
理解到泄漏的原因(handler持有了activity,然后message持有handler,然后MQ持有message),持有链了解清楚了也就好解决了:handler持有activity可以通过弱引用或者内部静态类等方式解决,removecallbacksandmessages则是清除后面的引用。
其实却是内存大,泄漏点也没啥,只是规范使然,就像过马路最好走斑马线,不然说不定哪天就被撞死了
mosentest commentedon Apr 8, 2019
对我而言,handler改为弱引用是一改而论(大家只考虑在activity问题,handler引用了activity),解决问题可以传activity弱引用给handler就行,或者在onresume恢复,onpause移除,谁能保证ondestroy能执行??万一没执行呢?如果在service后台用到handler,难道我也弱引用?合理使用handler,要明白为什么泄漏,不是所有场景都能用弱引用,没记错 高版本内存回收策略会先回收弱软引用,,,再说了,内存高就高,,,,,用户区能存活多久。。。
14 remaining items
frinda commentedon Aug 2, 2019
内存泄漏发生的主要原因:当前对象需要被销毁时,由其他对象(包含外部对象或者非静态内部类)持有当前对象的引用,导致当前对象释放不了;也可以抽象的说成是生命周期长的对象持有生命周期短的对象的引用
自定义 handler 导致内存泄漏发生的主要原因:当 activity 调用 finish 方法时,由于消息队列中有没被执行完的 message,message 持有 handler 的引用,handler 作为内部类又持有外部 activity 的引用,导致activity无法被释放;
解决办法:
Qiang11 commentedon Aug 2, 2019
直接清除队列里面的message不可以吗?
zhaoyujie commentedon Aug 2, 2019
看了大家写了这么多,还是很有收获的,目前基本都在使用 kotlin 开发,看见如上的回答中,有一个 kotlin 版本,写法比较奇怪,说一下自己的看法:
奇怪的地方:居然把一个所谓的静态内部类定义到了 companion object 模块 ???(该模块只用来定义静态字段和静态方法)
kotlin 中应该怎么写呢:
kotlin 的内部类需要用 inner class 关键字申明,不适用 inner 关键字修饰的类,称之为 嵌套类,不持有外部类的引用,请放心使用哈
Merpyzf commentedon Aug 3, 2019
千里之堤,毁于蚁穴
ZHANGfeng-james commentedon Aug 5, 2019
Handler 引起的内存泄露相关知识点:
siren4 commentedon Aug 12, 2019
1.自定义静态的Handler
2.非静态的Handler,可以加个弱引用(针对回调)
3.在onDestory时,调用removecallbacksandmessages(null)去清除Message和Runnable.
wangxuyang518 commentedon Aug 23, 2019
Handler内存泄露的根源:
1.内部类持有外部类的引用
2.Handler的message,没有清除
根据这俩点提出的解决方案:
1.将Handler自定义成静态类
2.清除Message
网友提的 弱引用算长知识了
xinyu618 commentedon Aug 27, 2019
1.将Handler自定义成静态类 弱引用Activity实例
2.清除Message
Mr-taotao commentedon Sep 29, 2019
1、静态内部类
2、弱引用外部类实例
3、及时移除Message
ddong1031 commentedon Mar 10, 2020
通常大家都喜欢在ondestory的时候调用mHandler.removeCallbacksAndMessages(null)
个人解答:
正常点击返回键的话onDestroy方法一定会执行。
如果是后台强杀的话当前仅有一个activity,这时候,强杀,是会执行onDestroy方法的;如果栈里面的第一个没有销毁的activity会执行ondestroy方法,其他的不会执行。
比如说:从mainactivity跳转到activity-A(或者继续从activity-A再跳转到activity-B),这时候,从后台强杀,只会执行mainactivity的onDestroy方法,activity-A(以及activity-B)的onDestroy方法都不会执行;
个人解答:
执行完上一个 Activity 的 onResume 之后,Activity 的销毁时通过请求 ActivityManagerService 的 activityIdle() 方法进行,实现的是 MessageQueue.IdleHandler,IdleHandler 会等到 MessageQueue 中当前没有可执行的消息时才会执行,也就是说 Activity 会一直等待主线程消息队列中当前消息都处理完毕了才会进行销毁,这也就是 Activity 的销毁不是立即执行的根本原因;通常代码解决都会定义一个基类的activity 如下
通过标志位 来判断是否是destroy的状态来加快释放的速度,算是优化的一点
yhxxxbl commentedon Oct 9, 2020
dalvik.vm.heapsize 指定了堆空间大小。不是12G的ram应用就能用12G的
zoomc commentedon Aug 20, 2021
现在手机内存比我电脑的都高
mlinqirong commentedon Dec 24, 2021
handler.removeCallbacksAndMessages(null)清空消息队列
tancolo commentedon Apr 22, 2024
群里给出的答案以及讨论都很不错,我这里结合Profiler 直观的将Activity泄漏不同情况展示出来。
具体的可以参考我这篇文章自定义Handler内存泄漏 (图文版)