什么情况导致 oom

时间:2022-02-12 16:22:49

OOM产生的原因:内存不足,android系统为每一个应用程序都设置了一个硬性的条件:DalvikHeapSize最大阀值64M/48M/24M.如果你的应用程序内存占用接近这个阀值,此时如果再尝试内存分配的时候就会造成OOM。

1)内存泄露多了就容易导致OOM

2)大图的处理。压缩图片。平时开发就要注意对象的频繁创建和回收。

3)可以适当的检测:ActivityManager.getMemoryClass()可以用来查询当前应用的HeapSize阀值。可以通过命名adb shellgetProp | grep dalvik.vm.heapxxxlimit查看。

如何避免内存泄露:

1) 减小对象的内存占用:

a)    使用更加轻量级的数据结构:

考虑适当的情况下替代HashMap等传统数据结构而使用安卓专门为手机研发的数据结构类ArrayMap/SparseArray。SparseLongMap/SparseIntMap/SparseBoolMap更加高效。

HashMap.put(string,Object);Object o = map.get(string);会导致一些没必要的自动装箱和拆箱。

b)    适当的避免在android中使用Enum枚举,替代使用普通的static常量。(一般还是提倡多用枚举---软件的架构设计方面;如果碰到这个枚举需要大量使用的时候就应该更加倾向于解决性能问题。)。

c)     较少Bitmap对象的内存占用。

使用inSampleSize:计算图片压缩比例进行图片压缩,可以避免大图加载造成OOM; decodeformat:图片的解码格式选择,ARGB_8888/RGB_565/ARGB_4444/ALPHA_8,还可以使用WebP。

d)    使用更小的图片

资源图片里面,是否存在还可以继续压缩的空间。

2) 内存对象的重复利用:

使用对象池技术,两种:1.自己写;2.利用系统既有的对象池机制。比如LRU(Last Recently Use)算法。

a)    ListView/GridView源码可以看到重用的情况ConvertView的复用。RecyclerView中Recycler源码。

b)    Bitmap的复用

Listview等要显示大量图片。需要使用LRU缓存机制来复用图片。

C)    避免在onDraw方法里面执行对象的创建,要复用。避免内存抖动。

D) 常见的java基础问题---StringBuilder等