If you read my last tutorial entry here, then you may have come across a problem with the code.

If you load several large bitmaps using the BitmapFactory class to decode the bitmap you application will give you the dreaded force close dialogue box. A quick look in the logcat shows that a bitmap exceeds the virtual machine memory budget.

1
ERROR/AndroidRuntime(750): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget

You may wonder how its possible that a few PNG’s can take up all the 16 mb of memory allocation for an application.

The cause is a a bug in the way that the Bitmap factory works.When it decodes the bitmap it keeps the data around even if the application is destroyed. So when it is recreated(like on a orientation flip), The bitmaps are still in memory.This means that when the application restarts the virtual machine tries to allocate the space it needs to decode the bitmap. Since you already have bitmaps there it runs out of space and triggers a crash.

There have been quite a few temporary work arounds suggested on the forums and mailing lists which require using the .Recycle() function on the bitmaps to release the memory. This is not really great for games since they generally need art assets all the time.

The solution I found to work perfectly so far is hidden in the 1.6 SDK changes.

The update to the Bitmap Factory class allows you to add some more option flags to decide how the bitmap is to be decoded. The key one we are interested in is the inPurgable option.You can check out the reference here, but in a nutshell it allows the Bitmap to be purged when it needs the memory at the expense of having to make a deep copy.

In order to use this just use the code below:

1
2
3
4
5
BitmapFactory.Options ops = new BitmapFactory.Options();
ops.inPurgeable = true;
 
mySprite = new AnimatedSprite();
mySprite.Initalise(BitmapFactory.decodeResource(res, R.drawable.idle, ops), 200, 150, 3, 10);

The only change to the Bitmap Factory call is to add the options flags as the second arguement of the decode resource call.Remember that this option is only in the 1.6 SDK.

This has solved all my problems with the Bitmap Size exceeds VM budget issues, Let me know how it works for you in the comments.

Stephen Flockton

  • Share/Bookmark