1、内存溢出的原因
1.1、内存泄漏
内存泄漏和内存溢出的区别:
内存泄漏:程序中存在对无用对象的引用,导致GC无法回收。内存泄漏最终会导致oom。
内存溢出:程序在申请内存时,没有足够的内存空间供其使用,出现out of memory。
1.2、保存多个耗用内存过大的对象
应用的某些逻辑操作消耗掉大量内存(譬如加载一张不经过处理的超大超高清图片等)导致超过阈值。
2、内存优化
2.1、bitmap
1)对bitmap进行压缩
通过BitmapFactory.Options设置inSampleSize采样率,并设置inJustDecodeBounds为true后图片就不会加载进内存,只是计算原始图片的大小,在对图片压缩处理完成之后,在设置为false就可以加载到内存了。
2)对bitmap进行回收
Bitmap 对象不再被使用的时候,调用Bitmap.recycle()方法来释放Bitmap占用的内存空间,并进行空引用,以便gc进行回收。
3)bitmap进行缓存
Bitmap缓存分为两种:一种是内存缓存,一种是硬盘缓存。
内存缓存(LruCache):
LruCache类是非常适合用作缓存Bitmap任务的,它将最近被引用到的对象存储在一个强引用的LinkedHashMap中,并且在缓存超过了指定大小之后将最近不常使用的对象释放掉。
2.2、修改对象引用类型
引用类型:
引用分为四种级别,这四种级别由高到低依次为:强引用>软引用>弱引用>虚引用。
1)强引用(strong reference)
如:Object object=new Object(),object就是一个强引用了。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。
2)软引用(SoftReference)
只有内存不够时才回收,常用于缓存;当内存达到一个阀值,GC就会去回收它;
3)弱引用(WeakReference)
弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它 所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。
4)虚引用(PhantomReference)
"虚引用"顾名思义,就是形同虚设,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。
但是对于SoftReference(软引用)或者WeakReference(弱引用)的Bitmap缓存方案,现在已经不推荐使用了。自Android2.3版本(API Level 9)开始,垃圾回收器更着重于对软/弱引用的回收。
2.3、适配器Adapter
1)复用用convertview
复用convertview布局文件的渲染次数,因为每次调用getView时都会重新创建View,这样之前的View可能还没有销毁,加之不断的新建View势必会造成内存泄露;
2)使用ViewHoder模式
使用viewhoder可以减少findviewbyid的次数,因为通过setTag将视图的tag存入一个数据结构,这个数据结构包含了指向我们要绑定数据的视图的引用;
2.4、其他
1)尽量少食用enmu
枚举相对于静态常量来说,需要两倍甚至更多的内存.
2)资源释放
使用数据库,IO流的时候记得关闭资源.