1.什么是oom(内存溢出)?
当前占用的内存加上我们申请的内存超过了Dalvik虚拟机的最大内存限制,就会抛出out of memory.
内存抖动
1.内存抖动:指在短时间内有大量的对象被创建或者被回收的现象。
2.内存抖动产生原因:主要是频繁(很重要)在循环里创建对象(导致大量对象在短时间内被创建,由于新对象是要占用内存空间的而且是频繁,如果一次或者两次在循环里创建对象对内存影响不大,不会造成严重内存抖动这样可以接受也不可避免,频繁的话就很内存抖动很严重),内存抖动的影响是如果抖动很频繁,会导致垃圾回收机制频繁运行(短时间内产生大量对象,需要大量内存,而且还是频繁抖动,就可能会需要回收内存以用于产生对象,垃圾回收机制就自然会频繁运行了)。
3.内存抖动影响:频繁内存抖动会导致垃圾回收频繁运行,造成系统卡顿。
内存泄露
对象不再被应用程序使用,但是垃圾回收器却不能移除它们,因为它们正在被引用。
2.解决oom内存溢出
1.bitmap
图片显示:
加载合适尺寸的图片,显示缩略图时不要网络请求加载大图,比如listview监听滑动时间,滑动时不网络请求,当滑动停止再加载大图绑定到imageview上。
及时释放内存:
Bitmap类有一个方法recycle(),从方法名可以看出意思是回收。这里就有疑问了,Android系统有自己的垃圾回收机制,可以不定期的回收掉不使用的内存空间,当然也包括Bitmap的空间。那为什么还需要这个方法呢?
Bitmap类的构造方法都是私有的,所以开发者不能直接new出一个Bitmap对象,只能通过BitmapFactory类的各种静态方法来实例化一个Bitmap。仔细查看BitmapFactory的源代码可以看到,生成Bitmap对象最终都是通过JNI调用方式实现的。所以,加载Bitmap到内存里以后,是包含两部分内存区域的。简单的说,一部分是Java部分的,一部分是C部分的。这个Bitmap对象是由Java部分分配的,不用的时候系统就会自动回收了,但是那个对应的C可用的内存区域,虚拟机是不能直接回收的,这个只能调用底层的功能释放。所以需要调用recycle()方法来释放C部分的内存。从Bitmap类的源代码也可以看到,recycle()方法里也的确是调用了JNI方法了的。
图片压缩:
图片的压缩是指我们需要根据View所实际需要的图片尺寸来加载对应大小的图片。一般我们用的图片加载第三方库,比如Glide,都已经帮我们做了处理。所以这里的图片压缩我们只需要在我们自己处理图片的时候需要考虑。
https://www.jianshu.com/p/e754244faa7b
inBitmap属性:
BitmapFactory.Options.inBitmap字段,设置此字段之后解码方法会尝试复用一张存在的Bitmap。Bitmap的内存被复用,避免了内存的回收及申请过程,显然性能表现更佳。
利用inBitmap的高级特性提高Android系统在Bitmap分配与释放执行效率(注:3.0以及4.4以后存在一些使用限制上的差异)。使用inBitmap属性可以告知Bitmap解码器去尝试使用已经存在的内存区域,新解码的Bitmap会尝试去使用之前那张Bitmap在Heap中所占据的pixel data内存区域,而不是去问内存重新申请一块区域来存放Bitmap。利用这种特性,即使是上千张的图片,也只会仅仅只需要占用屏幕所能够显示的图片数量的内存大小。
捕获异常
2.非bitmap
1.listview: convertview/LRU三级缓存机制
2.避免在onDraw方法中执行对象的创建。
类似onDraw等频繁调用的方法,一定需要注意避免在这里做创建对象的操作,因为他会迅速增加内存的使用,而且很容易引起频繁的gc,甚至是内存抖动。
3.谨慎使用多线程