Out of Memory Error Imageview Issue

Out Of Memory Error When loading more images in Glide

  • I solved this issue by removing nested scroll view placed above
    recyclerview. Why OutOfMemory error occurred means, when loading more
    than 200 images in home page, it is loading all 200 images because of using
    nested scroll view above recyclerview.

  • So I can't check the logcat image view width and height one by one in
    adapter.

  • After removed nested scroll view fixed out of memory error.because it
    will load only 3 images displayed in device when coming to home
    activity.

  • Also check
    this, how to use scroll instead of nested scroll view.

Android Out of memory error in Imageview

I added the following to my above code and got it to work. Its more or less related to what other individuals have mentioned here. So, thanks everyone for the help.

@Override
protected void onDestroy() {
System.gc();
super.onDestroy();
ivBackground.setImageBitmap(null);
}

android Image view out of memory error

in your code start at if(null != path) change to this

int size = 10; //minimize  as much as you want
if(path != null){
Bitmap bitmapOriginal = BitmapFactory.decodeFile(pathath);
Bitmap bitmapsimplesize = Bitmap.createScaledBitmap(bitmapOriginal,bitmapOriginal.getWidth() / size, bitmapOriginal.getHeight() / size, true);
bitmapOriginal.recycle();
img1.setImageBitmap(bitmapsimplesize);

}

android how to avoid this out of memory error

if image view hold an instance of bitmap drawable

Drawable drawable = imageView.getDrawable();
if(drawable!=null && BitmapDrawable.class.isAssignableFrom(drawable.getClass())) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Bitmap bitmap = bitmapDrawable.getBitmap();
if(bitmap != null && !bitmap.isRecycled()) bitmap.recycle();
}

but...

If you are loading bitmaps from drawable folders that are not large (large as in megabytes) then you should not really run into a problem.

If you loading assets you need to check if they are optimal for where you display them, for example there is no point in setting an ImageView to an image thats 1024 x 1024 in size if the area you display the image is a size of 64x64.

OOM often is caused by loading images of an unknown size or just simply getting the image sizes wrong as described above, swapping an ImageView frequently will generally not give you an issue with optimal sized images.

You should read some guidance on bitmaps:

https://developer.android.com/training/displaying-bitmaps/index.html

for your case:

this is essential fragment from stack trace :

FATAL EXCEPTION: main Process: ss.sealstudios.com.socialstories, PID: 13189 
java.lang.OutOfMemoryError: Failed to allocate a 2073612 byte allocation with 559872 free bytes and 546KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2738)
at android.content.res.Resources.loadDrawable(Resources.java:2643)
at android.content.res.Resources.getDrawable(Resources.java:833) at android.content.res.Resources.getDrawable(Resources.java:786)
at ss.sealstudios.com.socialstories.TwoFragment.prepareCardData(TwoFragment.java:280)

Failed to allocate a 2073612 byte allocation with 559872 free bytes and 546KB until OOM

so generally:

  • in method TwoFragment.prepareCardData(TwoFragment.java:280)
    befor call to Resources.getDrawable(..) you should get image view and recycle bitmap..
  • in fragment/activity you should also recycle bitmap in onDestroy() method

without more code i'm not able to determine if for example some loop is causing OOM or you are not releasing resources...

you can also do this (scale image) before settings up resource to image view:

Out of Memory Error ImageView issue

caution!!!

Do not use image you already recycled.

You'll get exception: Canvas: trying to use a recycled bitmap

bitmap.recycle() is not strictly required for android >2.3.3. If you still want to reclaim this memory forcefully, you'll have to find a way to check when the bitmap is indeed no longer needed (i.e., Canvas had a chance to finish its drawing operations).

the problem is that you probably making extensive use of Bitmaps (speed of allocation may be greater than speed at which bitmap getting recycled) then you might want to recycle unused bitmaps ASAP.You should call recycle() when you are done using the bitmap.

Always remember don't try to recycle bitmap when it is being shown on the screen.

So:

  • grab reference to old bitmap
  • set new one
  • invalidate view
  • check if old bitmap is not already recycled
  • recycle old one
  • you can also call System.gc(); ^

^Indicates to the VM that it would be a good time to run the garbage collector. Note that this is a hint only. There is no guarantee that the garbage collector will actually be run.

call to ImageView.setImageBitmap(); or similarity will not reclaim memory used by bitmap...

Why? because when u look at the impl of ImageView method especially:

private void updateDrawable(Drawable d) {
if (d != mRecycleableBitmapDrawable && mRecycleableBitmapDrawable != null) {
mRecycleableBitmapDrawable.setBitmap(null);
}
...

public void setImageResource(@DrawableRes int resId) {
// The resource configuration may have changed, so we should always
// try to load the resource even if the resId hasn't changed.
final int oldWidth = mDrawableWidth;
final int oldHeight = mDrawableHeight;

updateDrawable(null);
....

public void setImageBitmap(Bitmap bm) {
// Hacky fix to force setImageDrawable to do a full setImageDrawable
// instead of doing an object reference comparison
mDrawable = null;
if (mRecycleableBitmapDrawable == null) {
mRecycleableBitmapDrawable = new ImageViewBitmapDrawable(
mContext.getResources(), bm);
} else {
mRecycleableBitmapDrawable.setBitmap(bm);
}
setImageDrawable(mRecycleableBitmapDrawable);
}

See also:

https://developer.android.com/training/displaying-bitmaps/manage-memory.html

out of memory error imageview

Use this library to avoid OOM.

How to avoid Out of Memory Error while handling Imageviews

I would suggest to use a library to handle the loading, caching and displaying of images.
They are easy to use and you dont have to take care of image downsizing etc.

In my projects i use the Universal Image Loader by nostra13.
It is pretty easy to implement and offers a lot of features like memory and disk caching. You should give it a try.

Strange OutOfMemory issue while loading an image to a Bitmap object

The Android Training class, "Displaying Bitmaps Efficiently", offers some great information for understanding and dealing with the exception `java.lang.OutOfMemoryError: bitmap size exceeds VM budget when loading Bitmaps.



Read Bitmap Dimensions and Type

The BitmapFactory class provides several decoding methods (decodeByteArray(), decodeFile(), decodeResource(), etc.) for creating a Bitmap from various sources. Choose the most appropriate decode method based on your image data source. These methods attempt to allocate memory for the constructed bitmap and therefore can easily result in an OutOfMemory exception. Each type of decode method has additional signatures that let you specify decoding options via the 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 prior to the construction (and memory allocation) of the bitmap.

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

To avoid java.lang.OutOfMemory exceptions, check the dimensions of a bitmap before decoding it unless you absolutely trust the source to provide you with predictably sized image data that comfortably fits within the available memory.



Load a scaled-down version into Memory

Now that the image dimensions are known, they can be used to decide if the full image should be loaded into memory or if a subsampled version should be loaded instead. Here are some factors to consider:

  • Estimated memory usage of loading the full image in memory.
  • The amount of memory you are willing to commit to loading this image given any other memory requirements of your application.
  • Dimensions of the target ImageView or UI component that the image is to be loaded into.
  • Screen size and density of the current device.

For example, it’s not worth loading a 1024x768 pixel image into memory if it will eventually be displayed in a 128x96 pixel thumbnail in an ImageView.

To tell the decoder to subsample the image, loading a smaller version into memory, set inSampleSize to true in your BitmapFactory.Options object. For example, an image with resolution 2048x1536 that is decoded with an inSampleSize of 4 produces a bitmap of approximately 512x384. Loading this into memory uses 0.75MB rather than 12MB for the full image (assuming a bitmap configuration of ARGB_8888). Here’s a method to calculate a sample size value that is a power of two based on a target width and height:

public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;

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

final int halfHeight = height / 2;
final int halfWidth = 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;
}

Note: A power of two value is calculated because the decoder uses a
final value by rounding down to the nearest power of two, as per the
inSampleSize documentation.

To use this method, first decode with inJustDecodeBounds set to true, pass the options through and then decode again using the new inSampleSizevalue andinJustDecodeBoundsset tofalse`:

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);
}

This method makes it easy to load a bitmap of arbitrarily large size into an ImageView that displays a 100x100 pixel thumbnail, as shown in the following example code:

mImageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

You can follow a similar process to decode bitmaps from other sources, by substituting the appropriate BitmapFactory.decode* method as needed.



Related Topics



Leave a reply



Submit