0

我一直在制作一个模仿 ViewFlipper 的菜单系统,除了我亲自重置 RootView 中的图像和文本,试图避免与位图相关的 OOM。一切都很顺利,直到昨天我意识到在几次重新启动和随后的视图更改后,我会得到 Bitmap Exceeds VM budget.. 或类似的东西。我启动了分配跟踪器并试图查看没有被转储的内容,并发现这些调用是我的麻烦之源:

_stars.setBackgroundDrawable(getResources().getDrawable(R.drawable.star_1));
_button.setBackgroundResource(R.drawable.button_1); 
_image.setImageResource(R.drawable.image_1);

这显然不是所有代码,但它是跟踪器指向我的许多分配的地方,如下所示:

258 72  android.graphics.BitmapFactory$Options  1 android.graphics.drawable.Drawable
481 68  android.graphics.drawable.BitmapDrawable 1 android.graphics.drawable.Drawable
482 52  android.graphics.Paint  1   android.graphics.Bitmap createBitmap    
479 52  android.graphics.Paint 1 android.graphics.drawable.BitmapDrawable$BitmapState
255 36  android.graphics.Bitmap 1   android.graphics.BitmapFactory      
254 36  android.graphics.Canvas 1   android.graphics.Bitmap createBitmap    
250 36  android.graphics.Bitmap 1   android.graphics.Bitmap nativeCreate    
123 36  android.graphics.Bitmap 1   android.graphics.BitmapFactory

我想知道,这正常吗?还是我在某个地方有泄漏?测试后我的分配中至少有10-20个,最终我不可避免地遇到了 OOM。除了使用 Bitmap 变量和 Bitmap.recycle() 之外,不知道如何处理这个问题,但这涉及检查视图是否仍在使用以及可能在错误的时间回收;因此我不是粉丝。我只是在寻找一种在每次退出视图时杀死所有这些分配的方法。(已经尝试将控件设置为 null onPause() 和 onDestroy(),希望它们会释放对位图的引用,从而能够将它们 GC 到 NO AVAIL)

[编辑]

从那以后,我在这里读到,当您的活动完成时,Drawables 会根据需要进行处理。因此,我不应该对它们调用回收吗?至于单个位图的大小,它只是一张图像(480w x 720h (x4bpp/8))/1024 = ~169KB,所以这似乎不是问题。

4

1 回答 1

0

Exceeding the VM budget doesn't necessarily mean that there is a leak. I've cause the same issue by trying to load a single bitmap that was just way to big. Also, if you remove the reference, it may not GC right away anyway and you might still run out of memory. You may need to call .Recycle somehow, as I don't think there is a way to force GC run when you want it to, but Recycle will free native references held by the bitmap when you run it so you don't have to wait for a GC.

于 2011-08-08T19:10:14.307 回答