Android中常见的内存泄漏问题总结

检测内存泄漏的工具有LeakCanary、MAT等工具。

一、内存泄漏的原因:

当一个对象已经不需要使用,本该被回收,而另一个正在使用的对象持有它的引用,导致不能被回收,而停留在堆内存中,产生了内存泄漏。通常是Activity或者Fragment的泄露。

二、内存泄漏对程序的影响:

内存泄漏是造成应用程序OOM的主要原因之一。系统为每个应用程序分配的内存有限,当一个应用中产生的内存泄漏比较多时,难免会导致应用所需要的内存超过系统分配的内存限额,造成内存溢出而导致crash。

三、常见的内存泄漏:

1、单例造成的内存泄漏

由于单例的静态特性使得单例的生命周期和应用的生命周期一样长,如果一个对象已经不使用,而单例对象还持有该对象的引用,导致不能正常被回收,发生内存泄漏。


由于需要传入Context,这个Context的生命周期长短至关重要。

1)、传入的是Application的Context,这将没有任何问题,因为单例的生命周期和Application的一样长。

2)、传入的是Activity的Context。当这个Context所对应的Activity退出时,由于该Context和Activity的生命周期一样长,当前的Activity退出时它的内存并不会被回收,因为单例对象持有该Activity的引用。

正确的单例应用:

不管传入什么Context最终使用的Application的Context。

2、非静态内部类创建静态实例造成的内存泄漏。


非静态内部类默认会持有外部类的引用,而又使用该非静态内部类创建了一个静态的实例,该实例的生命周期和应用一样长,导致该静态实例会一直持有该Activity的引用,导致Activity的内存资源不能正常回收。

正确的做法是:将该内部类设为静态内部类或将该内部类变成一个单例。

3、Handler造成的内存泄漏。


由于mHandler是Handler的非静态匿名内部类的实例。所以它持有外部类Activity的引用。消息队列是在一个Looper线程中不断轮询处理消息,当这个Activity退出时消息队列中还有未处理的消息或者正在处理的消息,而消息队列中的Message持有mHandler实例的引用,mHandler又持有Activity的引用,导致该Activity的内存资源无法及时回收。

正确的做法是:

创建一个静态Handler内部类,然后对Handler持有的对象使用弱引用,这样在回收时也可以回收Handler持有的对象。在Activity的Destroy时或者Stop时应该移除消息队列中的消息。使用mHandler.removeCallbacksAndMessages(null);是移除消息队列中所有消息和所有的Runnable。当然也可以使用mHandler.removeCallbacks();或mHandler.removeMessages();来移除指定的Runnable和Message。

4、线程造成的内存泄漏。


上诉都是匿名内部类,对当前Activity都有一个隐式引用。如果在Activity销毁之前,任务还未完成,那么将导致Activity的内存资源无法回收,造成内存泄漏。

正确做法还是使用静态内部类的方式。

5、资源未关闭造成的内存泄漏。

对于使用BroadcastReceiver、ContentObserver、File、Cursor、Stream、Bitmap等,应该在Activity销毁时及时关闭或者注销,否则这些资源不会被回收,造成内存泄漏。

6、静态的View

有时,当一个Activity经常启动,但是对应的View读取非常耗时,我们可以通过静态View变量来保持对该Activity的rootView引用。这样就可以不用每次启动Activity都去读取并渲染View了。这确实是一个提高Activity启动速度的好方法!但是要注意,一旦View attach到我们的Window上,就会持有一个Context(即Activity)的引用。而我们的View有事一个静态变量,所以导致Activity不被回收。

解决办法:

  在使用静态View时,需要确保在资源回收时,将静态View detach掉。

7、监听器(各种需要注册的Listener,Watcher等)

例如:EditText的一个addTextChangeListener,如果在回调方法里有耗时操作,可能会造成内存泄露。

解决办法:

在onDestory时,取消注册,editText.removeTextChangedListener。

8、属性动画

在使用ValueAnimator或者ObjectAnimator,如果没有及时做cancel取消动画,就可能造成内存泄漏。

解决办法:在onDestory()调用动画的cancel()方法。cancel()方法最后调用了endAnimation()。

9、RxJava

在使用RxJava,如果发布一个订阅后,由于没有及时取消,导致Activity/Fragment无法销毁,导致内存泄漏。

解决方法:Android架构中添加AutoDispose解决RxJava内存泄漏

https://blog.csdn.net/mq2553299/article/details/79418068

10、WebView

在Android5.1及以上版本,webView可能存在内存泄漏。

解决办法:在销毁webview前一定要onDetachedFromWindow。先将webview从它的父view中移除再调用onDestory方法


Android5.1WebView内存泄漏及解决:https://blog.csdn.net/u013085697/article/details/53259116

11、其他系统控件以及自定义View

在 Android Lollipop 之前使用 AlertDialog 可能会导致内存泄漏:

https://blog.csdn.net/u012464435/article/details/50774580

Dialog和DialogFragment在Android5.0以下的内存泄漏:

https://www.cnblogs.com/endure/p/7664320.html

View的post方法导致的内存泄漏:

http://www.mamicode.com/info-detail-1753936.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270