Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
I guess the problem is not in your layout; the problem is somewhere else in your code. And you are probably leaking context somewhere.
Other probable reason is that you must be creating bulky multiple objects while parsing your XML (as you mentioned this occurs the first time when you parse XML). Though Java has auto garbage collection approach, but still you can not completely rely on it. It is a good practice to nullify your collection instance or clear your objects content when you don't need them any more.
But still I have prepared a list of important points which you should remember while dealing with bitmaps on Android.
1) You can call recycle on each bitmap and set them to null. (bitmap.recycle()
will release all the memory used by this bitmap, but it does not nullify the bitmap object).
2) You can also unbind the drawables
associated with layouts when an activity is destroyed. Try the code given below and also have a look at this link link.
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
// Call this method from onDestroy()
void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.RootView));
System.gc();
}
3) You can convert your hashmaps
to WeakHashmaps
, so that its memory would get released when the system runs low on memory.
4) You can scale/resize all your bitmaps. To scale bitmaps you can try something like this:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap=BitmapFactory.decodeStream(is, null, options);
This inSampleSize option reduces memory consumption.
Here's a complete method. First it reads the image size without decoding the content itself. Then it finds the best inSampleSize value; it should be a power of 2. And finally the image is decoded.
// Decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f){
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f),null,o);
// The new size we want to scale to
final int REQUIRED_SIZE=70;
// Find the correct scale value. It should be the power of 2.
int scale=1;
while(o.outWidth/scale/2 >= REQUIRED_SIZE && o.outHeight/scale/2 >= REQUIRED_SIZE)
scale*=2;
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize=scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
}
catch (FileNotFoundException e) {
}
return null;
}
Have a look at this link..
5) You can override onLowMemory()
method in an activity which gets a call when entire system runs low on memory. You can release a few resources there.
6) You can make your objects SoftReference
or Weakreference
, so that they get released in a low-memory condition.
A very common memory leak that I observed is due to the implementation of inner classes and implementing Handler
in Activity
. This links talks about the same in more detail.
I hope this helps to eliminate your problem.
java OutOfMemoryError: bitmap size exceeds VM budget
Well calling the system.gc() worked!!
Before the image is assigned to the imageView, i called the System.gc(), to take care of memory & it works.
Look at the modified code:
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK)
{
if (requestCode == SELECT_PICTURE)
{
// calling GC to take care of memory, if you remove this one line of code
// application will throw the error "VM out of memory error"
System.gc();
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
imageView.setImageURI(selectedImageUri);
}
}
}
Thanks @Torid.
Can someone comment on it? is this correct way to call the GC in this situation?
java.lang.outofmemoryerror bitmap size exceeds vm budget on bitmap
Error is due to the size of the image, i used this code to decrease the size of image when select from gallery.
public Bitmap setImageToImageView(String filePath)
{
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 1024;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true)
{
if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, o2);
return bitmap;
}
i hope this may helps you.
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
Use BitmapFactory.Options.inSampleSize
and set it to a value >1 which will scale it down.
java.lang.OutOfMemoryError: bitmap size exceeds VM budget in ListView and lazy loading images
It has been a nightmare and after days & nights of research here are few points that may be useful to others.
Don't store all the Bitmaps in cache. Keep it swapping between Disk cache and Memory Cache. Number of bitmaps you store can depend on the heap limit that you get by calling
int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE))
.getMemoryClass();
I used a LruCache
instead of WeakHashMap
cache. LruCache
is available in the support package. It is very easy to replace your existing WeakHashMap
implementation with LruCache
. Android also has a beautiful documentation on Caching Bitmaps.
Jake Wharton's DiskLruCache
is a great way to manage Disk Cache.
Don't download huge bitmaps if you do not need it. Try to get a size that's just good enough to fit your need.
Using BitmapFactory.Options you can make some trade offs with image quality to hold more images in memory cache.
If you think there's anything more we could do, please add.
Related Topics
How to Open a PDF via Intent from Sd Card
How to Solve Execution Failed for Task ':App:Compileflutterbuilddebug'
Android:Locationmanager VS Google Play Services
Display Badge on Top of Bottom Navigation Bar's Icon
How to Customize Item Background and Item Text Color Inside Navigationview
Android - Cannot Capture Backspace/Delete Press in Soft. Keyboard
Android: Using Webview Outside an Activity Context
Can't Run a Java Android Program with Valgrind
Phonegap - Forcing Landscape Orientation
Location Needs to Be Enabled for Bluetooth Low Energy Scanning on Android 6.0
Need an Example About Recyclerview.Adapter.Notifyitemchanged(Int Position, Object Payload)
How Can Make My Viewpager Load Only One Page at a Time Ie Setoffscreenpagelimit(0);
Progressdialog Is Deprecated.What Is the Alternate One to Use
Programmatically Collapse or Expand Collapsingtoolbarlayout
How to Set Default App Launcher Programmatically
How to Detect Whether the Android Phone in Silent Mode Programmatically