Bitmap recycle方法与制作Bitmap的内存缓存

来源:互联网 发布:第一款聊天软件 编辑:程序博客网 时间:2024/04/28 03:26

From: http://blog.csdn.net/a345017062/article/details/7963081

recycle方法不是必须调用,就算调了GC也不会立即回收Java层的Bitmap对象。这个跟把一个对象手动置空一个道理。可以看一下API说明:

This operation cannot be reversed, so it should only be called if you are sure there are no further uses for the bitmap. This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap. 


那么为什么程序中一般还需要调用呢?我们可以看一下recycle方法到底干了什么,下面是它的调用链:
Bitmap.recycle()(java)->nativeRecycle(mNativeBitmap)(java native)->SKBitmap::setPixels(NULL, NULL)(C++)->freePixels()(C++)
可以看出,recycle方法就是把C层的像素内存给释放了。我们知道,C层的内存还是算到当前进程的内存里的,而构成一个Bitmap对象的内存大部分都是C层的像素数组。所以,手动调用Bitmap.recycle并把Bitmap对象的Java层引用手动置NULL可以瞬间释放像素所占的内存,并让虚拟机下次运行时回收Bitmap对象所占的内存。不要忘了,因为包含了一堆的像素数据,Bitmap对象通常都很大。当很容易判断出这个图片不再被使用的时候就把它recycle一下吧。


但有一种情况比较除外,这就是程序中的列表界面,因为你不能判断用户会滚上还是滚下,而列表又比较长你不能保持所有的列表项中的图片。怎么办呢?
先说一个小测试:
[java] view plaincopy
  1. for (int i = 0; i < 1024; i++) {  
  2.     Bitmap b = Bitmap.createBitmap(1024*41024*2, Config.ARGB_8888);  
  3. }  

上面这段代码我运行了一下,没有报错。这验证了API文档中所说的,GC是可以自己回收Bitmap。这样,我们就可以有足够的理论支撑来使用SoftReference或者WeakReference制作一个内存缓存专门存放列表中的Bitmap了。网上讲强/软/弱引用时通常都会带着一个这样的例子,我就不再多说了,贴个网址,供参考:http://speed847.iteye.com/blog/374006
这里强调一下在制作内存缓存时使用软/弱引用的区别:
软引用:GC在分配对象时如果发现内存不足就会回收软引用的对象。
弱引用:只要GC一运行就会被回收。也可以用它来制作内存缓存,缺点就是如果其它模块频繁分配/释放对象造成GC运行比较频繁,缓存中的对象很可能会在内存很充裕的时候被清除,达不到缓存的目的了。

通常的内存缓存都是用软引用来制作。可以根据实际应用场景选择一个。


Android中的两种硬缓存
通常,借助于LinkHashMap我们可以很快建立一个硬缓存:
mLruMap = new LinkedHashMap<K, V>(16, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > intCapacity;
}
};
但这种方式是基于对象数量的缓存。今天发现了一个基于对象总容量的缓存——LruCache。这个类在android-support-v4.jar的util包中。
使用方式可以参考这个网址:http://geyubin.iteye.com/blog/1507567
0 0
原创粉丝点击