1

I get OutOfMemory when I have a lot of free space. I don't understand why. In my app I have a simple flow:

  1. Navigate to "take picture" functionality
  2. Take picture and display a thumbnail
  3. Resize and save taken picture (resize without Picasso help)
  4. Repeat 2 and 3 a few times
  5. Send taken pictures over the network.

Bellow is shown memory usage diagram for above steps. Everything work perfect. No OutOfMemory occurred.

enter image description here

But I've noticed one thing. A flow:

  1. Just before "take picture" functionality I have a menu. When I'm constantly switching orientation of the screen then memory usage increases (~2MB per switch).
  2. Take picture and display a thumbnail. Picture is taken but Picasso doesn't dispaly a thumbnail. I see that Picasso nicely handles OutOfMemory and doesn't stop the application. java.lang.OutOfMemoryError at android.graphics.BitmapFactory.nativeDecodeStream
  3. Resize and save causes the same OutOfMemory (java.lang.OutOfMemoryError at android.graphics.BitmapFactory.nativeDecodeStream) and stops the application

On the first diagram I see that "picture processing" takes ~20MB. On the second diagram I see that there is more than 20MB free but OutOfMemory occurs. Why? Garbage from switching orientation is collected.

enter image description here

1

1 Answer 1

2

On the second diagram I see that there is more than 20MB free but OutOfMemory occurs. Why?

Because you do not have a single block of free memory adequate to handle whatever allocation is failing, and you have hit your heap limit, so Android cannot expand the heap further.

In plain Java, the garbage collector is a "moving" collector, one that will move objects around in the heap in order to coalesce free blocks of memory. Hence, when you try to allocate something and the allocation fails, you really are out of memory.

Android, on the whole, does not employ a moving collector, because it would take up too much CPU time and harm the user experience. Hence, your heap space can become fragmented. You might have lots of free heap space, but they are all smaller than your desired allocation.

(the exception is on Android 5.0+, while your app is in the background, ART will use a moving collector)

Sign up to request clarification or add additional context in comments.

2 Comments

So what I can do about it? I can't target the application just for Android 5.0+. android:largeHeap=true helps but it's fishy
@emstol: "So what I coan do about it?" -- that is difficult to say, as we do not have a minimal reproducible example. In general, reuse your Bitmap objects via inBitmap on BitmapFactory.Options. Try not to hold onto a bunch of bitmaps in memory at once. Make sure that your resizing is doing that in a way that minimize heap usage (e.g., mostly via inSampleSize on BitmapFactory.Options, with fine tuning via other scaling). I have a conference video on memory management that may help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.