OOM out of memory(内存溢出)
最近做一个项目的时候,将测试切换到有大量数据的环境下,程序出现了OOM。在不懈努力下,终于在上线之前解决这个问题。
Android内存
Android系统的dalvik虚拟机会为每个应用程序分配堆内存,分配的堆内存的大小由机器的内存大小决定(这点和ios不一样,ios程序的应用内存几乎可以使用ios设备的整个内存空间,ios开发者几乎很少遇到OOM)。当你的程序需要一块新的内存时,系统会去申请Java空间,如果你申请的空间超过阈值,系统就会抛出OOM。
OOM原因
当你销毁一个对象的时候,系统会自动GC,释放资源,所以出现OOM无非就是以下两个原因:
(1)对象过大,系统无法分配资源,例如bitmap,file等大对象。
(2)GC问题,资源无法回收。例如static变量,context对象,handler对象
OOM主要问题与解决办法
问题1:加载大量图片时,OOM
这是OOM比较常见的问题,可以从以下方面优化:
(1)采用成熟的三方控件,如glide,fresco
(2)压缩图片,修改图片Bitmap.Config 为565
(3)如果允许,可以在手动清理内存中的图片缓存,如果是用的是列表,不建议这样处理,会导致列表往回滑时图片重新加载,消耗大量网络资源。
问题2:context资源无法释放
在Android开发中,必然会用到大量的context资源,但是有些时候,比如你写了一个静态的公共方法,你传了一个activity的context进去,然后你退出了这个activity,你以为你这个activity已经回收,但是并没有。
activity是有生命周期的,如果你的activity中的成员对象的生命周期超过了activity的生命周期,就会造成在activity销毁的时候,你的成员对象无法销毁。所以在使用context的地方,尽量使用application的context,application的生命周期贯穿整个程序,这样你的activity销毁后就不会存在于内存中了。
问题3:handler无法GC
当结束activity时,如果handler在主线程中,消息还在队列中没有处理,那么GC无法回收handler对象,也无法回收承载这个handler对象的activity。
使用静态内部类可以解决这个问题,使用activity的弱引用:
解决办法可以参照stack overflow:Handlers and memory leaks in Android - Stack Overflow
第一次写博客,写的不详细,请大家多多指教,后面我写写我是如何运用AS分析和优化内存