Skip to content Skip to sidebar Skip to footer

How Oom(out Of Memory Excepetion) Happens In Android?

I am trying to display an image from gallery or captured form camera in a ImageView. I started getting OOMs in the process. So I decided to find out how this works. So I tried with

Solution 1:

Ideally you will be using ARGB_8888 for bitmap. This means for each pixel 4 bytes are allocated (each one for A, R, G, B). It means that loading 1024x768 image takes 1024*768*4 = 3145728 B = 3072 KB = 3 MB. This is the reason why huge memory is used. The following info is taken from the documentation: http://developer.android.com/reference/android/graphics/Bitmap.Config.html

Bitmap.Config.ALPHA_8 - Each pixel is stored as a single translucency (alpha) channel.

Bitmap.Config.ARGB_4444 -This field was deprecated in API level 13. Because of the poor quality of this configuration, it is advised to use ARGB_8888 instead. Bitmap.Config.ARGB_8888 - Each pixel is stored on 4 bytes.

Bitmap.Config.RGB_565 - Each pixel is stored on 2 bytes and only the RGB channels are encoded: red is stored with 5 bits of precision (32 possible values), green is stored with 6 bits of precision (64 possible values) and blue is stored with 5 bits of precision.

Solution 2:

In Android every pixel of an image requires 4 bytes of memory. So if you create a Bitmap out of a 5 megapixel image, you'll need about 20MB. Therefore, you should calculate the required sample size to display the image without loading in the complete resolution.

Even if the image file is only 19KB, the Bitmap object will take up more memory.

Try creating a static method to calculate the required sample size:

publicstaticintcalculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of imagefinalintheight= options.outHeight;
finalintwidth= options.outWidth;
intinSampleSize=1;

if (height > reqHeight || width > reqWidth) {

    finalinthalfHeight= height / 2;
    finalinthalfWidth= width / 2;

    // Calculate the largest inSampleSize value that is a power of 2 and keeps both// height and width larger than the requested height and width.while ((halfHeight / inSampleSize) > reqHeight
            && (halfWidth / inSampleSize) > reqWidth) {
        inSampleSize *= 2;
    }
}

return inSampleSize;
}

and then check the bounds of the image first, before loading in the complete image:

publicstatic Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
    int reqWidth, int reqHeight) {

// First decode with inJustDecodeBounds=true to check dimensionsfinal BitmapFactory.Optionsoptions=newBitmapFactory.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);
}

More info on this is found in the developer guide: https://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Post a Comment for "How Oom(out Of Memory Excepetion) Happens In Android?"