什么情况导致OOM问题及如何优化

一、前期基础知识储备

(1)OOM定义—out of memory,内存溢出,一个程序中,已经不需要使用某个对象,但是因为仍然有引用指向它垃圾回收器就无法回收它,当该对象占用的内存无法被回收时,就容易造成内存泄露。多个内存泄漏最终会导致内存溢出,即OOM。

(内存泄漏和内存溢出两者之间的关系,可参考笔者之前的文章Android中内存泄漏详解》

(2)Java内存概念、内存泄漏相关知识点都可以参考笔者的文章Android中内存泄漏详解》

二、出现OOM错误的常见原因

(1)资源对象没关闭造成的内存泄露,try catch finally中将资源回收放到finally语句可以有效避免OOM资源性对象比如:

①Cursor游标对象没有关闭;

②调用registerReceiver后未调用unregisterReceiver();

③未关闭InputStream/OutputStream;

④Bitmap使用后未调用recycle()

(2)作用域不一样,导致对象不能被垃圾回收器回收,比如:

①非静态内部类会隐式地持有外部类的引用,

②Context泄露——概括一下,避免Context相关的内存泄露,记住以下事情:

  • 不要保留对Context-Activity长时间的引用(对Activity的引用的时候,必须确保拥有和Activity一样的生命周期)
  • 尝试使用Context-Application来替代Context-Activity
  • 如果你不想控制内部类的生命周期,应避免在Activity中使用非静态的内部类,而应该使用静态的内部类,并在其中创建一个对Activity的弱引用

③Thread 引用其他对象也容易出现对象泄露。

④onReceive方法里执行了太多的操作

(3)内存压力过大—最直接

①图片资源加载过多,超过内存使用空间,例如Bitmap 的使用,bitmap分辨率越高,所占用的内存就越大,这个是以2为指数级增长的;

②重复创建view,listview应该使用convertview和viewholder,ListView相关的知识点有两个:1)ListView的实现;2)ListView的效率优化,其中第二点对于开发者在使用ListView时是需要重点关注的,《第一行代码》中有相关介绍。

三、避免OOM的常用方法总结

1)资源文件需要选择合适的文件夹进行存放;

2)优化布局层次,越扁平化的视图布局,占用的内存就越少,效率越高;

3)减小Bitmap对象的内存占用;

4)使用更小的图片,是否存在可以压缩的空间,是否可以使用一张更小的图片;

5)复用系统自带的资源,比如字符串/颜色/图片/动画/样式以及简单布局等等,这些资源都可以在应用程序中直接引用;

6)注意在ListView/GridView等出现大量重复子组件的视图里面对ConvertView的复用;

7)类似onDraw等频繁调用的方法,一定需要注意避免在这里做创建对象的操作,因为他会迅速增加内存的使用,而且很容易引起频繁的gc,甚至是内存抖动;

8)在有些时候,代码中会需要使用到大量的字符串拼接的操作,这种时候有必要考虑使用StringBuilder来替代频繁的“+”;

9)考虑使用Application Context而不是Activity Context

总结:开发者做好内存优化,就像工程师处理好马达噪音问题一样,是一项长期的工作,需要注意的地方有很多,了解常用的,后期项目中碰到的也要自己总结好。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值