java.lang.OutOfMemoryError: bitmap size exceeds VM budget
I am trying to change the layout of my application from portrait to landscape and vice-versa. But if i do it frequently or more than once then at times my application crashes.. Below is the error log. Please suggest what can be done?
01-06 09:52:27.787: ERROR/dalvikvm-heap(17473): 1550532-byte external allocation too large for this process. 01-06 09:52:27.787: ERROR/dalvikvm(17473): Out of memory: Heap Size=6471KB, Allocated=4075KB, Bitmap Size=9564KB
01-06 09:52:27.787: ERROR/(17473): VM won't let us allocate 1550532 bytes
01-06 09:52:27.798: DEBUG/skia(17473): --- decoder->decode returned false
01-06 09:52:27.798: DEBUG/AndroidRuntime(17473): Shutting down VM
01-06 09:52:27.798: WARN/dalvikvm(17473): threadid=3: thread exiting with uncaught exception (group=0x4001e390)
01-06 09:52:27.807: ERROR/AndroidRuntime(17473): Uncaught handler: thread main exiting due to uncaught exception
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): java.lang.RuntimeException: Unable to start activity ComponentInfo{}: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2596)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3812)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.access$2300(ActivityThread.java:126)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1936)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.os.Handler.dispatchMessage(Handler.java:99)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.os.Looper.loop(Looper.java:123)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.main(ActivityThread.java:4595)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Method.invokeNative(Native Method)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Method.invoke(Method.java:521)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at dalvik.system.NativeStart.main(Native Method)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class <unknown
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.createView(LayoutInflater.java:513)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.inflate(LayoutInflater.java:385)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.Activity.setContentView(Activity.java:1629)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at onCreate(Game.java:98)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): ... 12 more
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: java.lang.reflect.InvocationTargetException
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.widget.LinearLayout.<init>(LinearLayout.java:92)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Constructor.constructNative(Native Method)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.LayoutInflater.createView(LayoutInflater.java:500)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): ... 22 more
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:464)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:340)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.content.res.Resources.loadDrawable(Resources.java:1705)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.content.res.TypedArray.getDrawable(TypedArray.java:548)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.View.<init>(View.java:1850)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.View.<init>(View.java:1799)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): at android.view.ViewGroup.<init>(ViewGroup.java:296)
01-06 09:52:27.857: ERROR/AndroidRuntime(17473): ... 26 more
Solution 1:
One of the most common errors that I found developing Android Apps is the
java.lang.OutOfMemoryError: Bitmap Size Exceeds VM Budget
error. I found this error frequently on Activities using lots of bitmaps after changing orientation: the Activity is destroyed, created again and the layouts are “inflated” from the XML consuming the VM memory available for bitmaps.
Bitmaps on the previous Activity layout are not properly deallocated by the garbage collector because they have crossed references to their activity. After many experiments I found a quite good solution for this problem.
First, set the “id” attribute on the parent view of your XML layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/RootView">
...
Then, on the onDestroy()
method of your Activity, call the unbindDrawables()
method passing a reference to the parent View and then do a System.gc()
.
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.RootView));
System.gc();
}
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();
}
}
This unbindDrawables()
method explores the view tree recursively and:
- Removes callbacks on all the background drawables
- Removes childs on every viewgroup
Solution 2:
I had got the java.lang.OutOfMemoryError: Bitmap Size Exceeds VM Budget error at several times
1) When switching from app and back to the app some time later (Press home button and after browsing some url)
2) When login/logout to app frequently (within 10 seconds)
3) When switching the device horizontally/vertically
Finally I solved the error in following way
public void clearAllResources() {
// Set related variables null
System.gc();
Runtime.getRuntime().gc();
}
Solution 3:
This is a practical answer, what I tried to avoid this problem at Run-time
Runtime.getRuntime().gc();
Calling Garbage Collector is a good Idea.