How can I fix frequent Out Of Memory Errors on Android emulators?

旧街凉风 提交于 2019-12-06 11:20:09

问题


I test a mobile app and have been struggling with constant crashes of the app when I use an Android emulator. I have no problem on physical Android devices, but emulators crash several times per day. The app will crash quite consistently once I find a crash-prone part of the app's "workflow". But exactly where in the app will trigger a crash seems to vary from version to version.

Here is the crash report:

Android: 2.3.7
Model: Full Android on x86 Emulator

java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:525)
at our.app.util.OurAppFileManager.getBrandingImageFromSD(OurAppFileManager.java:104)
at our.app.MainScreen.onResume(MainScreen.java:150)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1150)
at android.app.Activity.performResume(Activity.java:3832)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2110)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2135)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1668)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)

And here is a screenshot of my emulator settings:

I have tried changing the RAM and VM Heap and Internal Storage settings without much luck. In fact, the emulator launcher will start to complain if I set the RAM too high.


回答1:


You either truly have run out of heap space, or the heap is sufficiently fragmented that Android cannot allocate whatever you are requesting. This will happen on production devices as well, and so treating this as an emulator issue is a mistake IMHO.

I'd start by doing more testing with the 4.x emulator. Partly, that will give you better crash information, including how large of an allocation failed. Partly, it will give you substantially better results when using MAT to figure out where your heap is going.

There are umpteen zillion questions and answers here on StackOverflow regarding OutOfMemoryError with bitmap allocation. You may wish to browse through some. They will point you in the same basic directions:

  • On Android 3.0+, use inBitmap on the BitmapOptions that you pass to BitmapFactory, to reuse existing memory as opposed to allocating new memory

  • recycle() your Bitmap objects when you are done with them

  • Be generally careful about your memory allocations, as Android's garbage collector is non-compacting, so eventually you will be incapable of allocating large blocks of memory again

  • Use MAT to see if you are leaking memory somewhere that is contributing to your problem

And so on.




回答2:


Have a look at this Developer's Guide.

Use this workflow while decoding bitmap from external source:

private Bitmap decodeFile(File f, int reqHeight, int reqWidth){
    try {
        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);

        //Find the correct scale value. It should be the power of 2.
        int scale=1;
        while(o.outWidth/scale/2>=reqWidth && o.outHeight/scale/2>=reqHeight)
            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;
}

The important part is the inJustDecodeBounds.



来源:https://stackoverflow.com/questions/17537038/how-can-i-fix-frequent-out-of-memory-errors-on-android-emulators

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!