每日一道面试题(第5期)---哪些情况下会导致OOM问题

零零碎碎的东西总是记不长久,仅仅学习别人的文章也只是他人咀嚼后留下的残渣。无意中发现了这个每日一道面试题,想了想如果只是简单地去思考,那么不仅会收效甚微,甚至难一点的题目自己可能都懒得去想,坚持不下来。所以不如把每一次的思考、理解以及别人的见解记录下来。不仅加深自己的理解,更要激励自己坚持下去。

什么是OOM

“OOM”也就是“out of memory”,意思是内存用完了。也就是说,当你去申请内存的时候,你需要的内存过大,app剩下的空余内存已经不够你使用,如果你没有捕获这个异常,系统就没办法了,会直接崩溃并抛出OOM异常。

系统分配给每一个app运行的内存空间是有限的,所以作为一名Android开发者,我们一定要谨慎小心的使用内存。

OOM的类型

首先OOM的原因就是app进程可用内存不足,有两种情况

  • 内存申请的速度大于gc释放内存的速度
  • 内存出现泄漏,gc无法回收泄露的内存,导致可用内存越来越少

第一种情况又会有两种不同的类型

  • 一次性需要的内存过大,可用内存不足。常见的是使用图片资源时加载为bitmap存储到内存,图片分辨率越高,需要的内存就越大,就可能造成OOM。
  • 频繁的创建内存占用小的对象,导致内存碎片,这种叫内存抖动。虽然整体上还有内存可分配,但是这些内存空间并不连续,无法满足需求,导致OOM。常见的有ListView中contentView的创建、频繁使用String进行字符串的拼接、onDraw方法里对象的频繁创建。这一类问题要解决基本的方法就是复用已创建的对象

第二种情况就是内存泄漏,内存泄漏与OOM的关系就是量变到质变的过程,内存泄漏必定会导致可用内存的减少,大量的内存泄漏就会导致OOM问题。关于内存泄漏的具体例子在第3期已经很详细的探讨过,这里就不再赘述。

OOM的预防

这里总结几点,无非是两个方面:

  • 提高系统分配的可用内存。假如app确实需要很大的内存空间,那么可以再manifest文件中设置largeHeap="true"增加内存的的申请量
  • 减少app的内存使用
    • ImageView使用合适的尺寸,多图显示缩略图,点击查看大图
    • ListView使用ViewHolder复用contentView。不过现在大都用RecycleView,强制配合ViewHolder使用
    • 减少bitmap对象内存的占用,可用Lru缓存、三级缓存、合适的编码等
    • onDraw等频繁调用的方法中避免创建对象
    • 优化布局,少用LinerLayout多用RelativeLayout
    • 字符串拼接问题尽量使用StringBuilder而不是String的+

在内存泄漏方面

  • 使用静态内部类
  • 静态类引用使用Application的Context而不是Activity的Context
  • 类似广播、监听器等记得取消注册
  • 游标、文件等资源使用完毕一定要关闭
  • 静态集合使用完毕记得清空
  • 根据不同场景,善用软引用、弱引用

   转载规则


《每日一道面试题(第5期)---哪些情况下会导致OOM问题》 飞跃 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
每日一道面试题(第6期)---如何实现多线程中的同步 每日一道面试题(第6期)---如何实现多线程中的同步
零零碎碎的东西总是记不长久,仅仅学习别人的文章也只是他人咀嚼后留下的残渣。无意中发现了这个每日一道面试题,想了想如果只是简单地去思考,那么不仅会收效甚微,甚至难一点的题目自己可能都懒得去想,坚持不下来。所以不如把每一次的思考、理解以及别人
2020-03-31
下一篇 
每日一道面试题(第4期)---launchMode的应用场景 每日一道面试题(第4期)---launchMode的应用场景
零零碎碎的东西总是记不长久,仅仅学习别人的文章也只是他人咀嚼后留下的残渣。无意中发现了这个每日一道面试题,想了想如果只是简单地去思考,那么不仅会收效甚微,甚至难一点的题目自己可能都懒得去想,坚持不下来。所以不如把每一次的思考、理解以及别人
2020-03-31
  目录