Android Bitmap.createScaledBitmap throws java.lang.OutOfMemoryError mostly on Jelly Bean 4.1
Solution 1
http://www.youtube.com/watch?v=_CruQY55HOk. After andorid 3.0 bitmaps pixel data are stored on the heap. It seems you are exceeding heap memory size. Just because your app requires large heap do not use large heap. More the size of heap, more regular garbage collections. The video has a good explanation on the topic.
Also recycle bitmaps when not in use. Garbage collections on heap is done my mark and sweep , so when you recycle bitmaps it free's memory. So your heap size will not grow and run out of memory.
bitmap.recycle();
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html. Documentation on loading bitmaps efficiently. Have a look at loading scaled down version in memory.
Apart form this you can use Universal Image Loader. https://github.com/nostra13/Android-Universal-Image-Loader.
https://github.com/thest1/LazyList. Lazy Loading of Images.
Both use caching.
Solution 2
It's important to note that following code can cause Exception:
Bitmap bitmap = Bitmap.createScaledBitmap(oldBitmap, newWidth, newHeight, true);
oldBitmap.recycle();
Proper is:
Bitmap bitmap = Bitmap.createScaledBitmap(oldBitmap, newWidth, newHeight, true);
if (oldBitmap!= bitmap){
oldBitmap.recycle();
}
because documentation says:
If the specified width and height are the same as the current width and height of the source btimap, the source bitmap is returned and now new bitmap is created.
Solution 3
You are trying to access more memory then you have. Try to use
BitmapFactory.Options opts=new BitmapFactory.Options();
opts.inDither=false;
opts.inSampleSize = 8;
opts.inPurgeable=true;
opts.inInputShareable=true;
opts.inTempStorage=new byte[16 * 1024];
Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h1)
, 65,65, true),
Also look at below links to increase memory
http://developer.android.com/reference/android/R.styleable.html#AndroidManifestApplication_largeHeap
Detect application heap size in Android
EDIT 1
try to use nostras image downloader, you can use it to show image in local storage. And it manages memory very well ...
https://github.com/nostra13/Android-Universal-Image-Loader
![Rohit](https://i.stack.imgur.com/FowXJ.jpg?s=256&g=1)
Comments
-
Rohit about 2 years
My app main purpose is to display images in following fashion as shown in image
private void setSelectedImage(int selectedImagePosition) { BitmapDrawable bd = (BitmapDrawable) drawables.get(selectedImagePosition); Bitmap b = Bitmap.createScaledBitmap(bd.getBitmap(), (int) (bd.getIntrinsicHeight() * 0.9), (int) (bd.getIntrinsicWidth() * 0.7), false); selectedImageView.setImageBitmap(b); selectedImageView.setScaleType(ScaleType.FIT_XY); }
Detailed code can be find here
exception is thrown at following line
Bitmap b = Bitmap.createScaledBitmap(bd.getBitmap(), (int) (bd.getIntrinsicHeight() * 0.9), (int) (bd.getIntrinsicWidth() * 0.7), false);
Above function is called from
onItemSelected
. **The app still works well on 2.2 and 2.3, but throws exception immediately on 4.1 Above code works fine, but throws following exception. I didnot see any crashes in 2.2 and 2.3, but it immedidately crashes in 4.1 Is there any major difference of memory management in Jelly beans? **:java.lang.OutOfMemoryError AndroidRuntime(2616): at android.graphics.Bitmap.nativeCreate(Native Method) AndroidRuntime(2616): at android.graphics.Bitmap.createBitmap(Bitmap.java:640) AndroidRuntime(2616): at android.graphics.Bitmap.createBitmap(Bitmap.java:586) AndroidRuntime(2616): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:466) AndroidRuntime(2616): at com.rdx.gallery.GalleryDemoActivity.setSelectedImage(GalleryDemoActivity.java:183)
-
Rohit over 11 yearsusing bitmap.recycle() of not in use acutally helped.
-
Rohit over 11 yearsUsed bitmap.recycle for unused bitmaps. No more crashes on that module now. Thanks
-
Yoann Hercouet about 9 yearsThis code can still trigger exceptions if the bitmap was already recycled for any reason, you need to add this to the check: && !oldBitmap.isRecycled()
-
Malachiasz about 9 yearsIn which implementation of Bitmap class it is necessary? Because not in 5.1.0_r1, as the method checks it istelf: "if (!mRecycled && mFinalizer.mNativeBitmap != 0) " grepcode.com/file/repository.grepcode.com/java/ext/…