问题
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.
- Clearing my database and setting the large image to null in ondestroy() of my main activity.
- 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