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 theinSampleSize
documentation.
To use this method, first decode with inJustDecodeBounds
set to true, pass the options through and then decode again using the new
inSampleSizevalue and
inJustDecodeBoundsset to
false`:
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
Android Broadcast Receiver for Sent Sms Messages
Connecting 2 Emulator Instances in Android
Get the Background Color of a Button in Android
Android - How to Get the Processname or Packagename by Using Pid
How to Get Cell Service Signal Strength in Android
Pass Arraylist from One Activity to Other
Service Not Available - Geocoder Android
Phonegap - Forcing Landscape Orientation
Firebase: Query to Exclude Data Based on a Condition
Android App Crashing (Fragment and Xml Onclick)
How to Get Sms Sent Confirmation for Each Contact/Person in Android
Loading Youtube Video Through Iframe in Android Webview
Convert Magnetic Field X, Y, Z Values from Device into Global Reference Frame
How to Access Getsupportfragmentmanager() in a Fragment