Search code examples
androidcanvasbitmapimageviewbitmapfactory

"Out of VM budget" on 2.3.3 and "trying to use recycled image" on 2.2 with the same code


I am tired of trying every possibility in stackoverflow and googled alot...... not getting what i want.

bt=BitmapFactory.decodeResource(getResources(), dressarray[indexdress],options);
//Background1 = getApplicationContext().getResources().getDrawable(dressarray[indexdress]);
bt1=Bitmap.createBitmap(bt);
dress.setImageBitmap(bt1);

i have this code in various if else conditions... dress in code is ImageView there are lots of images on my screen.. there are 10 ImageButtons and for those i have 1 onClick method which performs above operation on particular ImageView by checking which button is pressed.

at last i call a method to recycle bitmap(which is my last variation before asking question) inside onClick. call to that method is the last line in onClick

here is the method to recycle

public void callrecycle()
    {
        bt.recycle();
        bt=null;
        bt1=null;
        System.gc();
    }

now problem is i hav an emulator with HTC EVO screen density and resolution with platform 2.3.3 an a second emulator with density 180 resolution 320X480 and platform 2.2

on 2.3.3 i get an error

07-06 10:42:41.898: D/dalvikvm(420): GC_EXTERNAL_ALLOC freed <1K, 52% free 2611K/5379K, external 19034K/19732K, paused 55ms
07-06 10:42:41.918: E/dalvikvm-heap(420): 1382400-byte external allocation too large for this process.
07-06 10:42:42.028: I/dalvikvm-heap(420): Clamp target GC heap from 25.682MB to 24.000MB
07-06 10:42:42.028: E/GraphicsJNI(420): VM won't let us allocate 1382400 bytes
07-06 10:42:42.028: D/dalvikvm(420): GC_FOR_MALLOC freed <1K, 52% free 2611K/5379K, external 19034K/19732K, paused 35ms
07-06 10:42:42.028: D/AndroidRuntime(420): Shutting down VM
07-06 10:42:42.028: W/dalvikvm(420): threadid=1: thread exiting with uncaught exception (group=0x40015560)
07-06 10:42:42.050: E/AndroidRuntime(420): FATAL EXCEPTION: main
07-06 10:42:42.050: E/AndroidRuntime(420): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
07-06 10:42:42.050: E/AndroidRuntime(420):  at android.graphics.Bitmap.nativeCreate(Native Method)
07-06 10:42:42.050: E/AndroidRuntime(420):  at android.graphics.Bitmap.createBitmap(Bitmap.java:477)
07-06 10:42:42.050: E/AndroidRuntime(420):  at android.graphics.Bitmap.createBitmap(Bitmap.java:432)
07-06 10:42:42.050: E/AndroidRuntime(420):  at android.graphics.Bitmap.createBitmap(Bitmap.java:383)
07-06 10:42:42.050: E/AndroidRuntime(420):  at android.graphics.Bitmap.createBitmap(Bitmap.java:367)
07-06 10:42:42.050: E/AndroidRuntime(420):  at com.internetdesignzone.dressup.DressUp$1.onClick(DressUp.java:334)
07-06 10:42:42.050: E/AndroidRuntime(420):  at android.view.View.performClick(View.java:2485)
07-06 10:42:42.050: E/AndroidRuntime(420):  at android.view.View$PerformClick.run(View.java:9080)
07-06 10:42:42.050: E/AndroidRuntime(420):  at android.os.Handler.handleCallback(Handler.java:587)
07-06 10:42:42.050: E/AndroidRuntime(420):  at android.os.Handler.dispatchMessage(Handler.java:92)
07-06 10:42:42.050: E/AndroidRuntime(420):  at android.os.Looper.loop(Looper.java:123)
07-06 10:42:42.050: E/AndroidRuntime(420):  at android.app.ActivityThread.main(ActivityThread.java:3683)
07-06 10:42:42.050: E/AndroidRuntime(420):  at java.lang.reflect.Method.invokeNative(Native Method)
07-06 10:42:42.050: E/AndroidRuntime(420):  at java.lang.reflect.Method.invoke(Method.java:507)
07-06 10:42:42.050: E/AndroidRuntime(420):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-06 10:42:42.050: E/AndroidRuntime(420):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-06 10:42:42.050: E/AndroidRuntime(420):  at dalvik.system.NativeStart.main(Native Method)
07-06 10:42:44.968: I/Process(420): Sending signal. PID: 420 SIG: 9

and on 2.2 aget an error with same piece of code

07-06 10:35:37.929: D/dalvikvm(351): GC_EXTERNAL_ALLOC freed 3K, 52% free 2620K/5379K, external 6273K/7166K, paused 59ms
07-06 10:35:38.249: D/AndroidRuntime(351): Shutting down VM
07-06 10:35:38.271: W/dalvikvm(351): threadid=1: thread exiting with uncaught exception (group=0x40015560)
07-06 10:35:38.329: E/AndroidRuntime(351): FATAL EXCEPTION: main
07-06 10:35:38.329: E/AndroidRuntime(351): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4051e4c8
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.graphics.Canvas.throwIfRecycled(Canvas.java:955)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.graphics.Canvas.drawBitmap(Canvas.java:1044)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:325)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.widget.ImageView.onDraw(ImageView.java:854)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.View.draw(View.java:6880)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.View.draw(View.java:6883)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.View.draw(View.java:6883)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.widget.FrameLayout.draw(FrameLayout.java:357)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.View.draw(View.java:6883)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.widget.FrameLayout.draw(FrameLayout.java:357)
07-06 10:35:38.329: E/AndroidRuntime(351):  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1862)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.ViewRoot.draw(ViewRoot.java:1522)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.ViewRoot.performTraversals(ViewRoot.java:1258)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.os.Handler.dispatchMessage(Handler.java:99)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.os.Looper.loop(Looper.java:123)
07-06 10:35:38.329: E/AndroidRuntime(351):  at android.app.ActivityThread.main(ActivityThread.java:3683)
07-06 10:35:38.329: E/AndroidRuntime(351):  at java.lang.reflect.Method.invokeNative(Native Method)
07-06 10:35:38.329: E/AndroidRuntime(351):  at java.lang.reflect.Method.invoke(Method.java:507)
07-06 10:35:38.329: E/AndroidRuntime(351):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-06 10:35:38.329: E/AndroidRuntime(351):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-06 10:35:38.329: E/AndroidRuntime(351):  at dalvik.system.NativeStart.main(Native Method)
07-06 10:35:40.789: I/Process(351): Sending signal. PID: 351 SIG: 9

can anybody tell me the reason? and please tell me how can i reuse recycled bitmap. i don want to reduce the quality of bitmap.

the options i am passing have

inPurgeable=true
inInputShareable=true

Note: if i dont use Bitmap thing and directly write dress.setImageResource(dressarray[indexdress]);

the app works like a champ in 2.2 but closes with Out Of Budget on 1st click on 2.3.3 and dressarray[indexdress] is an array of images containing R.drawble.imgid and all are PNG images


Solution

  • I solved this issue at that time by using downgraded images.

    You can avoid this error by using inSampleSize & inPurgeable in options. and reusing the same Bitmap variable and making it null after every use.

    call System.gc() wherever possible. it doesn't call gc but gives hit that it can be started.

    inPurgeable will make ur bitmap object cleanable while doing gc().

    inSampleSize will downgrade bitmap so use a proper value.

    also you can resize your bitmap while creating so that it can reduce its size. use createScaledBitmap()

    Hope it help others.