Android Honeycomb中的Bitmap#recycle()实际上做了什么?

And*_*yld 15 memory android bitmap recycle android-3.0-honeycomb

我正在为Android Honeycomb编写一个内存密集型应用程序,并且尽可能地对recycle()未使用的Bitmaps 进行了非常小心的处理.实际上,这对于应用程序来说是必要的,因为Bitmaps不断地循环进出内存.但是,我刚刚实现onConfigurationChanged()Activity,因此(由于多种原因)我试图将内存释放例程放入其中onStop().

目前我的onStop()方法:

  • 设置一些Views来显示默认值Drawable;
  • 呼吁recycle()Bitmap以前使用的这些小号View秒;
  • nulls对Bitmaps的引用.

不幸的是,使用Eclipse内存分析器,它似乎对内存使用没有任何影响.

你可以想象,我已经做了很多努力,用一种名义上垃圾收集的语言来释放资源,我希望能有更多的效果.所以我的问题是:做recycle()什么?它是否实际上触发了垃圾收集,或者系统是否会保留在内存中 - 即使你调用System.gc()-until它感觉需要摆脱某些东西?

NB我知道Bitmaps实际上并没有被保存在常规堆中,但我认为调用recycle()足以确保它们被从本机堆中删除.

答案的一部分

我发现如果一个ImageView包含Bitmap已经被回收的Bitmap数据,那么数据仍会保留在内存中,直到setImageBitmap(null)被调用ImageView.甚至可能是这种情况,如果setImageResource(...)或被setImageDrawable(...)调用(它们是在一个相对较小的九个补丁中加载 - 但是,MAT分析显示这并没有删除Bitmap包含在私有成员中的大数据ImageView).简单地调用此函数onStop()已经从我们的应用程序堆中剔除了大约10MB.显然,这可能不适用于预装的Honeycomb版本的Android.

Tor*_*rid 6

正如Justin所说,Bitmap数据没有在VM堆中分配.VM堆中有一个引用(很小),但实际数据由底层Skia图形库在Native堆中分配.[请注意,这可能在以后的Android级别中发生了变化,但对于2.1和2.2也是如此]当您执行recycle()时,它会将VM堆中的一小部分和本机堆中的实际数据标记为空闲且可用于GC.但实际的收集是由两种不同的GC机制完成的.VM堆中的部分由Davlik GC收集 - 您可以通过DDMS看到这种情况.但是,Skia GC收集了本机堆数据,这看起来更加懒散(运行频率较低?).这意味着,即使使用严格的recycle(),也可以超越本机堆GC.幸运的是,有一些机制可以监视本机堆的状态.看看BitmapFactory OOM让我疯狂.


And*_*yld 6

我发现,在Honeycomb之后,如果一个ImageView包含Bitmap已被回收的Bitmap数据,则数据仍保留在内存中,直到setImageBitmap(null)在ImageView上调用.甚至可能是这种情况,如果setImageResource(...)或被setImageDrawable(...)调用(在这种情况下,一个非常大的位图被一个相当小的九个补丁替换,但只有setImageBitmap(null)在加载九补丁之前被调用的是实际处理的内存).

  • 一个重要的注意事项:在ICS中的位图上显式调用recycle()会导致致命的崩溃.典型 - 您必须*在早期版本中进行回收以避免内存泄漏,并且您*不得*在ICS上再循环以避免崩溃.谢谢,Google ...... (3认同)
  • @Adrian,你有更多细节吗?我有一个应用程序在许多不同的ICS设备上运行,使用了recycle()并且没有看到崩溃.如果你有一些关于我的信息,我很乐意看到它,以确保我没有做一些危险的事情. (2认同)