Rectangle 27 1

Android Bitmap Memory Issue Error: Out of memory on a 8294416 byte allocation?


private Bitmap scaleBitmap(String path, long maxImageMemory)
{
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, options);

    int sample = 1;
    //Scale image to screen resolution
    if (options.outHeight > app.getHeight() || options.outWidth > app.getWidth())
    {
        int heightRatio = Math.round((float) options.outHeight / (float) app.getHeight());
        int widthRatio = Math.round((float) options.outWidth / (float) app.getWidth());
        sample = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    //Scale image to stay within memory limitations
    while (calcBitmapSize(options.outWidth, options.outHeight, sample) > maxImageMemory)
    {
        sample++;
    }

    options.inSampleSize = sample;
    options.inPurgeable = true;
    options.inInputShareable = true;
    options.inJustDecodeBounds = false;

    Log.i(TAG, "scaleBitmap, scaleSample = " + sample);
    return BitmapFactory.decodeFile(path, options);
}
private ImageView newImage(Show show, long maxImageMemory)
{
    ImageView iv = new ImageView(this);
    String filePath = comin.generateFilePath(show);
    Bitmap bmp = scaleBitmap(filePath, maxImageMemory);
    Log.i(TAG, "newImage, id:" + show.id + ", file:" + filePath + ", x:" + bmp.getWidth() + ", y:" + bmp.getHeight());
    iv.setImageBitmap(bmp);
    iv.setScaleType(ImageView.ScaleType.FIT_XY);
    iv.setId(show.id);

    //set visibility
    if (show.visible)
        iv.setVisibility(View.VISIBLE);
    else
        iv.setVisibility(View.INVISIBLE);

    //set dimensions
    int width = (app.getWidth() * show.dimX) / 100;
    int height = (app.getHeight() * show.dimY) / 100;
    RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(width, height);
    iv.setLayoutParams(rlp);

    return iv;
}
private long calcAvailableMemory()
{
    long value = Runtime.getRuntime().maxMemory();
    String type = "";
    if (android.os.Build.VERSION.SDK_INT >= 11)
    {
        value = value / 1024) - (Runtime.getRuntime().totalMemory() / 1024);
        type = "JAVA";
    }
    else
    {
        value = value / 1024) - (Debug.getNativeHeapAllocatedSize() / 1024);
        type = "NATIVE";
    }
    Log.i(TAG, "calcAvailableMemory, size = " + value + ", type = " + type);
    return value;
}
private long calcBitmapSize(int width, int height, int sample)
{
    long value = ((width/sample) * (height/sample) * 4) / 1024;
    Log.i(TAG, "calcBitmapSize, size = " + value);
    return value;
}
private void logMemory(String callingFunction)
{
    long max = Runtime.getRuntime().maxMemory() / 1024;

    if (debugJavaMemory)
    {
        long used = Runtime.getRuntime().totalMemory() / 1024;
        long available = max - used;
        long change = available - availableJavaMemoryOld;
        if (availableJavaMemoryOld != 0)
            Log.i(TAG_MEMORY, "jMEM M:" + max + ", U:" + used + ", A:" + available + ", C:" + change + ", " + callingFunction);
        availableJavaMemoryOld = available;
    }
    else if (debugNativeMemory)
    {
        long used = Debug.getNativeHeapAllocatedSize() / 1024;
        long available = max - used;
        long change = available - availableNativeMemoryOld;
        if (availableNativeMemoryOld != 0)
            Log.i(TAG_MEMORY, "nMEM M:" + max + ", U:" + used + ", A:" + available + ", C:" + change + ", " + callingFunction);
        availableNativeMemoryOld = available;
    }
}

I wasn't able to determine why memory allocation and collection is different among the different platforms, but I was able to mitigate the problem and prevent my application from crashing on any platform by scaling the images down to fit available memory.

Lastly, I developed this function to assist in troubleshooting all of these memory problems. It logs memory utilization depending on which version of Android you are running.

This first function determines where the Bitmap memory is being stored (native or Java), and then calculates the remaining available memory (in KB).

This fourth function calculates the amount of memory required by the Bitmap depending on the original resolution, as well as the proposed sample size.

This second function creates an ImageView to attach to the Layout. The Show object contains different variables I need to initialize the ImageView such as dimensions and filepath etc. The long maxImageMemory is derived from the first function, and is then divided by the number of views I'm attaching to the layout giving the me maximum amount of memory to allocate each Bitmap.

This third function scales the Bitmap that will be loaded into the ImageView being created in function 2. The while loop is the important part, that is where I increase the sample size until the needed memory for the bitmap is less than the maximum memory available.

Note
Rectangle 27 1

Android Bitmap Memory Issue Error: Out of memory on a 8294416 byte allocation?


BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap bitmap = BitmapFactory.decodeStream(fis, null, options);

I have had this problem couple of months ago, try this,may help:

Thank you for your comment, but I currently have a dynamic down sampling function which I made courtesy of the Android Training at developer.android.com/training/displaying-bitmaps/index.html The function ends up returning a sampleSize value of 1, since the resolution matches the image. Each image appears to use around 8MB of memory (as seen in the logs). If one scene only has 4 images it would be a grand total of 32MB, or about half of the available memory.

Note
Rectangle 27 1

Android Bitmap Memory Issue Error: Out of memory on a 8294416 byte allocation?


Thank you for your comment, but I have already been through that training. The app is designed to load the images from the SD card. Please explain your reasoning that the folder your store your image in would help decrease memory utilization or release the memory when needed.

This link may help you http://developer.android.com/training/displaying-bitmaps/load-bitmap.html This problem also arises when the drawable is not available in the drawable-xhdpi folder for the large 720x1280 mobiles. Please cross check it that the drawables you are using are in the correct drawable folder.

Note
Rectangle 27 1

Android Bitmap Memory Issue Error: Out of memory on a 8294416 byte allocation?


Thank you for your comment, but I have already been through that training. The app is designed to load the images from the SD card. Please explain your reasoning that the folder your store your image in would help decrease memory utilization or release the memory when needed.

This link may help you http://developer.android.com/training/displaying-bitmaps/load-bitmap.html This problem also arises when the drawable is not available in the drawable-xhdpi folder for the large 720x1280 mobiles. Please cross check it that the drawables you are using are in the correct drawable folder.

Note