Android内存如何泄露

Android内存如何泄露

  1. 对象的生命周期溢出
  2. 对象无限创建引起内存爆满

生命周期溢出

内存泄露说到底是,对象的生命周期管理失误,导致对象的生命周期溢出。大概可以理解成,儿子变成了兄弟(O_O),所以不再管的了他。

生命周期溢出.png

如图,对象B本来由对象O管理,但由于使用失误导致对象B溢出了本来的生命周期,由儿子变成了兄弟。

此处对象B发生了内存泄露,场景可以参照:

  1. 对象B被程序级变量保存,如单例模式,全局静态变量,程序级对象持有等等。
  2. 对象B内调用了registerReceiver注册广播或注册到Android系统服务,把自己托付给了Android系统。
  3. 对象B内使用了非静态内部类(匿名或非匿名一样),不小心跟着内部类跑出了生命周期。
  4. 对象B跑到了另一个线程,认了另一个爸爸。比如Handler,Runnable,AsyncTask等。
  5. 占有了系统资源不释放。比如File,Stream,Cursor等。
    无论哪种,都是生命周期没管理好导致的问题。

当对象O释放的时候,如下图,对象O变成了待释放,当GC后,就只剩对象B还活着。


等待GC.png
GC后.png

此过程,大致有以下两点:

  1. 对象没有被GCRoot引用,对象占用的内存并不是立即释放,而是等待下一次GC。
  2. 内存泄露只泄漏那个泄露的对象占用的内存。比如对象B内有一个Bitmap,如果对象O释放的时候同时释放了对象B内的Bitmap,那么对象B泄露的只是一个空壳对象,泄漏几个字节;反之,如果没有时机释放对象B内的Bitmap,则对象B泄露的就是一个Bitmap几十兆的内存。(前者长时间运行内存不怎么涨,Crash几率低,比较难发现;后者短时间运行内存就爆满,容易Crash,相对容易发现)

当出现内存泄露后,不断重复操作,就会出现下面的现象,一堆对象B挂在树上,像葫芦娃。这种现象和下面对象不断创建类似,但本质是不一样的。


QQ20171211-170140@2x.png

这是常见的内存泄露模型。但也有一直保持两个的。为什么呢?因为再次操作,新的对象B替代了旧的对象B,使得旧的对象B得到了释放的机会。最简单的就是setObject(B)这种设置属性的操作,新的对象B会替换旧的对象B。这也是常见的泄漏模型。

如何避免生命周期溢出?
最简单的原则是,主动管理内部对象或线程的生命周期。

首先,不要假想Android系统或第三方接口会帮我们管理传递给他们的对象。就好比假想handler或postDelay会在退出的时机释放所有Runnable一样,这个假设即使成立,也应当自己主动管理。然后

注意下面的类型:

  1. 静态变量(静态属性或全局静态变量)。
  2. 单例模式(单独拿出来是因为大部分人不怎么注意单例)。
  3. 内部类(匿名或非匿名),要么主动释放要么改为静态内部类。
  4. Runnable/Handler/AsyncTask/post/postDelay等线程操作,主动释放。
  5. 资源操作,切记释放。
  6. 系统服务,申请或注册后主动释放和反注册。
  7. 避免引用传递过深。

对象不断创建,内存爆满

内存问题另一个是,逻辑错误导致对象不断创建,最后导致内存爆满。这并不是内存泄露,而是属于没有正确和合理使用内存。

内存爆满.png

和上面内存泄露不停创建对象区别是,这里更偏向于方案不合理,方案本身出了内存问题。而不是由于生命周期管理失当,溢出引发的。

注意下面的方案:

  1. 多线程/并发。避免多线程处理多张图片!(解码过程瞬间撑爆内存)
  2. 对象缓存。列表的ItemView缓存要适当,含有图片时用完最好先释放图片后再加入缓存重用。一些缓存机制也要注意。
  3. (大)对象集合。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...
    _痞子阅读 1,652评论 0 8
  • 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏大家都不陌生了,简单粗俗的讲,...
    宇宙只有巴掌大阅读 2,399评论 0 12
  • Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏...
    apkcore阅读 1,237评论 2 7
  • 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问题。内存泄漏大家都不陌生了,简单粗俗的讲,...
    DreamFish阅读 802评论 0 5
  • 紧握兄弟姐妹的手团结成天梯,攀登梦想的蓝天,超越最强的我。 ——《碧桂园营销人之歌》 从拓展基地回到总部,我们的亢...
    最强能力者培训第四期阅读 1,110评论 0 0