位图内存泄漏?
我一直在制作一个模仿 ViewFlipper 的菜单系统,除了我亲自重置 RootView 中的图像和文本,试图避免与位图相关的 OOM。一切都很顺利,直到昨天我意识到在几次重新启动和随后的视图更改后,我会得到位图超出虚拟机预算..或类似的东西。我启动了分配跟踪器并尝试查看哪些内容没有被转储,并发现这些调用是我的麻烦根源:
_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 它们而无济于事)
[编辑]
我已经读过 此处,当您的活动时,Drawables 将根据需要进行处理完成了。因此,我不必对它们调用回收,不是吗?至于单个Bitmap的大小,它只是一张图像(480w x 720h (x4bpp/8))/1024 = ~169KB,所以看起来不太像成为问题。
I've been making a menu system that mimics ViewFlipper except I personally reset the images and text within the RootView myself, trying to avoid Bitmap related OOM. All was going well until yesterday when I realized after a few restarts, and subsequent view changes, I'd get the Bitmap Exceeds VM budget.. or something alike. I started allocation tracker and tried to see what wasn't being dumped, and found these calls my source of trouble:
_stars.setBackgroundDrawable(getResources().getDrawable(R.drawable.star_1));
_button.setBackgroundResource(R.drawable.button_1);
_image.setImageResource(R.drawable.image_1);
This obviously isn't all the code, but it's where the tracker is pointing me for the MANY allocations like this:
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
What I'm wondering, is this normal? Or do I have a leak somewhere? There are at least 10-20 of each of these in my allocations after the test, and inevitably I hit OOM eventually. Not sure how to take care of this other than using a Bitmap variable, and then Bitmap.recycle() possibly, but that involves checking if the view is still being used and possibly recycling at the wrong time; hence I'm not a fan. I'm more just looking for a way to kill all of these allocations every time I exit view.(already tried setting the controls to null onPause() & onDestroy(), hoping they'd release the references to the bitmaps, and thus be able to GC them to NO AVAIL)
[edit]
I've since read here that Drawables get handled as necessary when your activity is finished. So therefore I shouldn't have to call recycle on them should I? As for the size of the single Bitmap, it is just one image (480w x 720h (x4bpp/8))/1024 = ~169KB, so that doesn't seem to be the issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
超出虚拟机预算并不一定意味着存在泄漏。我通过尝试加载一个太大的位图而导致了同样的问题。另外,如果删除引用,它可能不会立即进行 GC,并且您仍然可能会耗尽内存。
您可能需要以某种方式调用
.Recycle
,因为我认为没有办法在您想要的时候强制 GC 运行,但是Recycle
将释放所持有的本机引用当你运行它时通过位图,这样你就不必等待 GC。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, butRecycle
will free native references held by the bitmap when you run it so you don't have to wait for a GC.