java.lang.OutOfMemoryError: bitmap size exceeds VM budget

41,518

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:

  1. Removes callbacks on all the background drawables
  2. 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.

Solution 4

Add this line of code to Android Manifest File inside "application" tag: - android:largeHeap="true"

<application
         android:theme="@android:style/Theme.NoTitleBar"
        android:allowBackup="true"
        android:largeHeap="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
       >

Solution 5

You can fix the problem using opts.inSampleSize=2; or opts.inSampleSize=4

BitmapFactory.Options opts = new BitmapFactory.Options();
// opts.inJustDecodeBounds = true; 
opts.inSampleSize=2;    
Bitmap myBitmap = BitmapFactory.decodeFile(st_imagepath,opts);
Share:
41,518

Related videos on Youtube

Angel
Author by

Angel

I am a software developer...

Updated on July 09, 2022

Comments

  • Angel
    Angel over 1 year

    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 
    
    • J-16 SDiZ
      J-16 SDiZ about 13 years
      next time, use the "format code" button, not the "block quote" button. the blockquote button mess up the message
    • Ashish Dwivedi
      Ashish Dwivedi
      I am also getting this error, but there are no any solution. I am getting this error when i am trying to get the frame of video file from MetaDataRetriver class, My Code MediaMetadataRetriever mRetriever = new MediaMetadataRetriever(); mRetriever.setDataSource(this.videoPath); for (int i = 0; i < TimeUnit.MILLISECONDS .toMicros(listVideoFileDuration.get(k)); i = i + 5000000) { Bitmap oragnalBitmap = mRetriever.getFrameAtTime(i, MediaMetadataRetriever.OPTION_NEXT_SYNC); }
  • cV2
    cV2 over 12 years
    this fixed the problem for my case... always got a layoutinflate exception on inflating a large layout with many graphics after time... thanks!
  • Mario Lenci
    Mario Lenci about 12 years
    greate code... only bug i had with this is when there are adapterView in the layout. They cause a UnsupportedOperationException on the removeAllViews(), just added a try catch on that line and everything worked fine.
  • Maxrunner
    Maxrunner about 12 years
    How do you deal with background images added with the setTheme method??
  • swiftBoy
    swiftBoy over 11 years
    still didn't get any luck :(
  • William
    William over 10 years
    As the Android performance documentation states you should not be attempting to force the GC, you should let Davlik handle it itself. At best this hiding the cause of your memory issue and substituting a CPU performance loss.
  • zhaojing
    zhaojing about 9 years
    @Rafiq, could you please explain when to call this function clearAllResources()?

Related