Android性能优化之内存优化总结
一、常见内存问题
1、内存抖动
内存抖动一般指在很短的时间内发生率多次内存的分配和释放,主要因为短时间内频繁创建对象,内存为了应对这种情况也会进行频繁的GC,造成内存抖动。
2、内存溢出
我们的手机会给每个app分配一个最大的内存,这个大小与手机本身配置有关。一旦app所需的内存超过了手机分配的内存,就会发生内存溢出,即OOM(out of memory)。
3、内存泄漏
一般指该被回收的对象持有其他对象引用导致不能被回收,一般是短生命周期对象被长生命周期对象持有引用。
二、内存抖动
2.1、常见现象
内存抖动根本原因是在短时间内频繁创建对象,例如:
1、在循环体内创建对象。
2、View的OnDraw()调用频繁,在这里创建对象可能产生大量对象。
3、Listview频繁创建子item。
2.2、解决办法
尽量避免在循环体或者调用频率很高的代码内创建对象,必须重复创建的时候尽量复用已存在的对象(如Listview的ViewHolder复用)。
三、内存溢出
3.1、常见现象
1、加载高清大图
2、页面需要加载图片数量多
3、读取大文件内容
3.2、解决办法
加载图片需要压缩,按需加载不同分辨率图片。读取文件内容分段读取,尽量不要一次性读取整个文件(如读取本地小说按页面显示需要读取部分行,而不是一次性加载到内存).
四、内存泄漏现象及解决
1、集合类
现象:集合添加元素后,仍然引用着元素,导致该元素无法被回收。
解决方案:使用后清空集合对象并且置为null。
2、static关键字修饰的成员变量
泄漏原因:静态变量生命周期与application生命周期一致,如果它引用了其他对象,则会造成其他对象使用完毕后无法回收。
例如 :
private static Context mContext;
// 引用的是Activity的context
mContext = context;
解决方法:尽量避免静态资源引用非静态资源,若需要context尽量使用application的context。
使用弱引用代替强引用持有实例。
3、非静态内部类、匿名类
原因:外部类默认持有内部类的对象,所以内部类默认持有外部类的引用。
解决方案:使用静态内部类。
4、多线程
原因:多线程也属于非静态内部类、匿名类。当工作线程正在执行任务时,持有外部类引用造成外部类无法回收。
泄漏条件:工作线程正在正在运行并且持有外部类引用。
解决方案:泄漏条件之一不满足即可解决。所以解决方法为:外部类activity生命周期结束时强制结束任务或者将thread子类设置成静态类。
5、handle造成的内存泄漏
原因:handle非静态内部类持有外部类引用。有消息未处理,message持有handle的引用。
解决方案:
方式一:静态类handle并且外部引用activity设置为弱引用。
方式二:在activity生命周期结束onDestroy()时清空handle消息,handle.removeCallbacksAndMessages(null);
为了保证handle内的所有消息都能执行,最好使用方式一来解决泄漏问题。
6、资源对象使用后未关闭
解决方案:在使用完毕后关闭资源,如广播解注册、文件流关闭、数据库游标关闭、图片bitmap recycle、无限循环动画退出。