大家都知道,Android开发中,如果涉及到大量bitmap的处理,一个不小心就会发生OOM。所以,对我来说,当bitmap对象不再需要的时候,及时recycle掉,几乎是常识一样自然的事情。
去年做一个项目的时候,刚好让控件组的同事看了一下我的代码。他说他们组做过测试,感觉recycle没什么用。不过控件用到的图片相对都比较小,所以也不好判断。
之后看了一下源码,是这么描述recycle的:
/** * Free the native object associated with this bitmap, and clear the * reference to the pixel data. This will not free the pixel data synchronously; * it simply allows it to be garbage collected if there are no other references. * The bitmap is marked as "dead", meaning it will throw an exception if * getPixels() or setPixels() is called, and will draw nothing. 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. */ public void recycle() { if (!mRecycled && mNativePtr != 0) { if (nativeRecycle(mNativePtr)) { // return value indicates whether native pixel object was actually recycled. // false indicates that it is still in use at the native level and these // objects should not be collected now. They will be collected later when the // Bitmap itself is collected. mBuffer = null; mNinePatchChunk = null; } mRecycled = true; } }
这是API 25的代码,可以看到注释里面有这么一句,“This will not free the pixel data synchronously; it simply allows it to be garbage collected if there are no other references.”。
我的理解就是,recycle确实不是立即回收对应bitmap的内存,因为不是synchronously嘛。
那么,不调用recycle行吗?
特别是上面的注释里面写了:
* 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的引用置为null。至于以前都要求对bitmap主动recycle,不要等GC,是有其历史原因的。
我是通过这篇帖子 《Bitmap.recycle引发的血案 》http://www.jianshu.com/p/b5c8e98ff5b0 找到了官方的两个说明网页:
https://developer.android.google.cn/topic/performance/graphics/manage-memory.html#recycle
https://developer.android.google.cn/topic/performance/graphics/cache-bitmap.html
而从上面的链接中,可以得到如下信息:
On Android 2.3.3 (API level 10) and lower, the backing pixel data for a bitmap is stored in native memory. It is separate from the bitmap itself, which is stored in the Dalvik heap. The pixel data in native memory is not released in a predictable manner, potentially causing an application to briefly exceed its memory limits and crash. As of Android 3.0 (API level 11), the pixel data is stored on the Dalvik heap along with the associated bitmap.
On Android Android 2.2 (API level 8) and lower, when garbage collection occurs, your app's threads get stopped. This causes a lag that can degrade performance. Android 2.3 adds concurrent garbage collection, which means that the memory is reclaimed soon after a bitmap is no longer referenced.
那么,现在还有人要兼容 A