Android:位图回收()如何工作?
比方说,我已经加载了像位图对象的图像
Bitmap myBitmap = BitmapFactory.decodeFile(myFile);
现在,如果我加载另一个位图会发生什么
myBitmap = BitmapFactory.decodeFile(myFile2);
第一个myBitmap发生了什么,它会得到垃圾收集或我必须手动垃圾收集它加载之前,另一个位图,例如。 myBitmap.recycle()
还有一种更好的方式来加载大图像并在路上循环显示它们
当您解码第二个位图时,第一个位图不会被GC化。 GC将在稍后决定时再做。 如果要尽快释放内存,则应在解码第二个位图之前调用recycle()。
如果你想加载真正的大图像,你应该重新采样。 下面是一个示例将图像加载到Bitmap对象时出现的内存不足问题 。
加载下一个图像之前,您需要调用myBitmap.recycle()。
根据myFile的来源(例如,如果它是你无法控制的原始大小的东西),加载图像,而不是简单地重新采样一些任意数字,你应该缩放图像的显示大小。
if (myBitmap != null) { myBitmap.recycle(); myBitmap = null; } Bitmap original = BitmapFactory.decodeFile(myFile); myBitmap = Bitmap.createScaledBitmap(original, displayWidth, displayHeight, true); if (original != myBitmap) original.recycle(); original = null;
我cachingdisplayWidth&displayHeight在静态,我在我的活动开始初始化。
Display display = getWindowManager().getDefaultDisplay(); displayWidth = display.getWidth(); displayHeight = display.getHeight();
我认为问题是这样的:在Honey之前版本的Android中,实际的原始位图数据不是存储在虚拟机内存中,而是存储在本地内存中。 当相应的Java Bitmap
对象是GC'd时,这个本地内存被释放。
但是 ,如果用完本机内存,dalvik GC不会被触发,所以应用程序可能只使用很less的java内存,所以不会调用dalvik GC,但它会使用大量的本地内存来存储位图最终导致OOM错误。
至less这是我的猜测。 幸运的是,在Honeycomb以后,所有的位图数据都存储在虚拟机中,所以你根本不必使用recycle()
。 但是,对于数以百万计的2.3用户(碎片摇头 ),你应该尽可能使用recycle()
(一个巨大的麻烦)。 或者,您也可以调用GC来代替。
一旦位图被加载到内存中,实际上是由两部分数据组成的。 第一部分包括一些关于位图的信息,另一部分包括关于位图像素的信息(它由字节数组构成)。 第一部分存在于Java使用的内存中,第二部分存在于C ++中使用的内存中。 它可以直接使用对方的内存。 Bitmap.recycle()用于释放C ++的内存。 如果你只是这样做,GC将收集的Java部分和C的内存总是使用。
Timmmm是对的。
根据: http : //developer.android.com/training/displaying-bitmaps/cache-bitmap.html
另外,在Android 3.0(API Level 11)之前,位图的备份数据被存储在本地存储器中,而不是以可预见的方式释放,这可能导致应用程序暂时超出其内存限制和崩溃。