android Bitmap的内存管理

我们在显示图片的时候总是会用到Bitmap,但是Bitmap如果没有恰当的使用的话效率会很低也很容易会出现oom错误。

下面是一段摘自官网的话:

在Android 2.2 (API level 8)以及之前,当垃圾回收发生时,应用的线程是会被暂停的,这会导致一个延迟滞后,并降低系统效率。 从Android 2.3开始,添加了并发垃圾回收的机制, 这意味着在一个Bitmap不再被引用之后,它所占用的内存会被尽快回收。在Android 2.3.3 (API level 10)以及之前, 一个Bitmap的像素级数据(pixel data)是存放在Native内存空间中的。 这些数据与Bitmap本身是隔离的,Bitmap本身被存放在Dalvik堆中。我们无法预测在Native内存中的像素级数据何时会被释放,这意味着程序容易超过它的内存限制并且崩溃。 自Android 3.0 (API Level 11)开始, 像素级数据则是与Bitmap本身一起存放在Dalvik堆中。

所以我们在API level 10之前并不能很好的管理Bitmap,推荐使用recycle方法,该方法可以使得程序更快的释放内存。在使用该方法时必须确保这个Bitmap已经不再使用。否则会错。这是针对API level 10之前的方法。

从Android 3.0 (API Level 11)开始,引进了BitmapFactory.Options.inBitmap字段。 如果使用了这个设置字段,decode方法会在加载Bitmap数据的时候去重用已经存在的Bitmap。这意味着Bitmap的内存是被重新利用的,这样可以提升性能,并且减少了内存的分配与回收。然而,使用inBitmap有一些限制,特别是在Android 4.4 (API level 19)之前,只有同等大小的位图才可以被重用。具体怎么利用已经存在的Bitmap呢,这就需要结合软引用,首先软引用并不会妨碍垃圾收集线程对该Bitmap(java对象)的回收,在Bitmap被回收之前,如果你使用了软引用的get方法,你就会得到这个Bitmap对象的强引用,如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。而当Bitmap已经被回收,get方法会返回空。注意软引用要与ReferenceQueue结合使用,下面举例说明

ReferenceQueue queue = new  ReferenceQueue();
    SoftReference  ref=new  SoftReference(aMyObject, queue);

aMyObject是一个对象,如果此对象被垃圾回收机制回收了,那么这个对象的软引用ref就会被加入到queue队列中,我们要做的就是清除这个队列中的对象(一般会在另一个list中存那些软引用),讲简单一点就是先将那些软引用存在一个地方,给我们复用,而queue的作用就是清理没用的软引用(就是get之后返回空的那些软引用),具体如何使用可以参考: http://zhangjunhd.blog.51cto.com/113473/53092/

回到Bitmap的问题上,结合了软引用之后,就可以在可用的软引用队列中拿到那些可以复用的Bitmap,就帮我们节省了内存和创建的时间,提高了效率。

android官网中有相应的demo:请查看:http://developer.android.com/intl/zh-cn/training/displaying-bitmaps/manage-memory.html


你可能感兴趣的:(android,内存管理)