我在很多示例中看到开发人员在位图上调用recycle()
,然后将其设置为null
。
这是为什么呢?垃圾回收器不能负责释放位图吗?
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
bitmap.recycle();
bitmap = null;
我在很多示例中看到开发人员在位图上调用recycle()
,然后将其设置为null
。
这是为什么呢?垃圾回收器不能负责释放位图吗?
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
bitmap.recycle();
bitmap = null;
加入俱乐部吧。它有点道理但不完全正确。
问题在于,在 Android Honeycomb 版本之前,位图的内存是从非托管内存中分配的(现在仍然是这样),这会创建各种问题。它仍然会被释放,但是从位图对象实现的终结器中释放。这意味着至少需要 2 次 GC 才能收集它。此外,如果由于某种原因终结器未能执行 - 你懂的。还有一件事- 它真的很难追踪 - DDMS 看不到它,MAT 也看不到。
对于 Android 3.0,这已经改变了,位图是通过托管的字节数组实现的,但是对于旧手机……
bitmap.recycle();释放在位图中使用的本地堆,将其设置为null是为了帮助GC快速收集您的引用。
来自http://developer.android.com/reference/android/graphics/Bitmap.html#recycle%28%29上的文档。
释放与此位图关联的本地对象,并清除对像素数据的引用。这不会同步释放像素数据;如果没有其他引用,它只是允许垃圾回收。该位图被标记为“死亡”,这意味着如果调用getPixels()或setPixels(),它将抛出异常,并且不会绘制任何内容。此操作无法撤消,因此仅在确保没有进一步使用位图时才应调用它。这是一个高级调用,通常不需要调用,因为当没有更多引用此位图时,正常的GC过程将释放此内存。
所以似乎没有必要去调用。我曾经听说过唯一需要手动将对象设置为null的情况是,如果它是静态变量(或某个不容易超出范围的变量)并且您想将其强制从内存中移除。也许,如果您不断地快速分配位图,则可能需要尝试强制进行垃圾回收,但对于大多数情况来说,这可能是不必要的。
recycle()
,但自己调用它可以更快地释放内存,从而减少堆空间不足的可能性。 - CommonsWare