Android app crash out of memory on relaunch

痞子三分冷 提交于 2019-12-22 10:56:09

问题


So I'm having an infamous oom error caused by large bitmaps. But I've managed to fix most of the issues. The only issue remaining happens when I click back and close the app and then launch the app right after. Then the app will crash giving me a oom (out of memory) error. This wont happen if I click home.

Why is this happening? My guess is that the GC hasn't finished clearing up and now I start it up while the old data is still lying around. And of course it isn't a new app so the old launch and the new launch goes under the same app memory limitation.

Any inputs on this issue and possible solutions would be great.

What I've tryed:

On all download of bitmaps I've used:

BitmapFactory.Options op = new Options();
op.inPurgeable = true;
bmImg = BitmapFactory.decodeStream(is,null,op);

Making the images smaller in dimensions width x height (the size in kb is approximately the same). <-- This solves the problem so I have a fall-back solution unless there is someone out there with a super solution :)

Snippet of error log:

06-25 04:29:28.917: E/AndroidRuntime(8819): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:715)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.content.res.Resources.loadDrawable(Resources.java:1713)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.widget.ImageView.<init>(ImageView.java:122)
06-25 04:29:28.917: E/AndroidRuntime(8819):     at android.widget.ImageView.<init>(ImageView.java:112)
06-25 04:29:28.917: E/AndroidRuntime(8819):     ... 23 more

Edit: So two things fix this issue for me.

  1. Clearing my database and setting the large image to null in ondestroy() of my main activity.
  2. Making the large images smaller.

But this just raises the same fundamental question, if onDestroy() is called, why isn't my activity closed properly before a new one is opened? Also I see my activity keep on running long after it is closed. Could this be related to the issue? How do I track down the cause of this?

Edit2: The culprint seems to be my LruCache. I use a static lrucache which isn't cleared in ondestroy(). When the app is restarted all the images in the lrucache is still present which causes problems. I'm still wondering why this only is a problem on restart? Shouldn't this also be a problem when I return to my main activity just before I close it?


回答1:


I had the same problem which was solved by force closing the process. This can be done by overriding onDestroy(). Use this:

@Override
public void onDestroy(){
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> pids = am.getRunningAppProcesses();
    for (int i = 0; i < pids.size(); i++) {
        ActivityManager.RunningAppProcessInfo info = pids.get(i);
        if (info.processName.equalsIgnoreCase(context.getPackageName())) {
            android.os.Process.killProcess(info.pid);
        }
    }
    super.onDestroy();
}



回答2:


Hey please check my answer on the same issue: bitmap size exceeds Vm budget error android

And also always try to use maximum options while dealing with bitmaps like this:

        final Options options = new Options();
        options.outHeight = (int) scaleHeight; // new smaller height
        options.outWidth = (int) scaleWidth;   // new smaller width
        options.inScaled = true;
        options.inPurgeable = true;

        // to scale the image to 1/8
        options.inSampleSize = 8;
        bitmap = BitmapFactory.decodeFile(imagePath, options);

This might solve your problem.




回答3:


The culprint seems to be my LruCache. I use a static lrucache which isn't cleared in ondestroy(). When the app is restarted all the images in the lrucache is still present which causes problems. I'm still wondering why this only is a problem on restart? Shouldn't this also be a problem when I return to my main activity just before I close it?

Nevertheless my temp/permanent fix of this issue is to clean all static references in ondestroy(), but also to use images of smaller size. This seems to solve all my problems as I'm also not able to find any memory leaks.



来源:https://stackoverflow.com/questions/11082820/android-app-crash-out-of-memory-on-relaunch

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