What is a Memory Heap Size in android? and how can use Bitmap Efficiently?

By | August 25, 2013

Memory Heap Size

Android is a full multitasking system so it’s possible to run multiple programs at the same time and obviously each one can’t use all of your device memory.
For this reason there is a hard limit on your Android application’s heap size: if your application needs to allocate more memory and you have gone up to that heap size already, you are basically going to get a “out of memory error”.
Heap size limit is device dependent and it has changed a lot over the years, the first Android phone (the G1) has 16MB heap size limit, now we have tablets like Motorola Xoom that have 48MB heap size limit.
The basic reason is that new tablets and new phones have an high monitor resolution so they need more memory in order to draw more pixels.
However this limit is also too tight for a new kind of application that you can image for a tablet. For example, think about a photo editor that is really memory intensive, probably 48MB of heap space isn’t enough for that.
For that kind of application Honeycomb introduced an option in the Android Manifest: “android:largeHeap=true” that give you a big heap space limit.”
This doesn’t mean that if you get an “out of memory error” you can fix it simply setting this option!
You have to use this option only if you are going to build an application that is really memory intensive and you really need it.
When you develop an application you have to think that your application will run on a very large set of different devices with different capability and different heap size limit, so you need to worry about that and a simple thing you can do it’s provide your bitmap resources in all the different resolution ldpi, mdpi, hdpi, xhdpi.

Handle bitmap efficiently

If you’re not careful, bitmaps can quickly consume your available memory budget leading to an application crash due to the dreaded exception: “java.lang.OutofMemoryError: bitmap size exceeds VM budget”.

Images come in all shapes and sizes. In many cases they are larger than required for a typical application user interface (UI).
Given that you are working with limited memory, the best thing that you can do is to load a lower resolution version into the memory. The lower resolution version should match the size of the UI component that displays it. An image with an higher resolution does not provide any visible benefit, but still takes up precious memory and incurs additional performance overhead due to additional on the fly scaling.
The BitmapFactory class provides several decoding methods (decodeByteArray(), decodeFile(),decodeResource(), etc.) for creating a Bitmap from various sources.
Each type of decode method has additional signatures that let you specify the decoding options via BitmapFactory.Options class.
Setting the inJustDecodeBounds property to true while decoding avoids memory allocation, returning null for the bitmap object but setting outWidth, outHeight and outMimeType. This technique allows you to read the dimensions and type of the image data before the construction (and memory allocation) of the bitmap.
Now that the image dimensions are known, they can be used to decide if we should load the full image or a subsampled version, into the memory. To tell the decoder to subsample the image, loading a smaller version into memory, set inSampleSize to the scale factor in your BitmapFactory.Options object.
The code below shows how to load an Image of arbitrarily large size to a bitmap of the reqWidth and reqHeight.
The calcualteInSampleSize just determinates the scale factor from the original size and the requested size.

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {
    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
 
    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
 
    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

References:
http://android-developers.blogspot.it/2011/03/memory-analysis-for-android.html
http://android-developers.blogspot.it/2009/01/avoiding-memory-leaks.html
http://developer.android.com/training/displaying-bitmaps/index.html

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

Leave a Reply

Your email address will not be published. Required fields are marked *