3

I am seeing the following thing in my adb logcat window:

01-24 14:40:56.916: E/dalvikvm-heap(24727): 1957200-byte external allocation too large for this process.
01-24 14:40:56.966: E/GraphicsJNI(24727): VM won't let us allocate 1957200 bytes
01-24 14:40:56.976: E/dalvikvm(24727): OutOfMemory: max: 50331648(49152 K), total: 39985120(39047 K), alloc: 33659240(32870 K), extAlloc: 8993870(8783 K)

What I don't understand is why these numbers don't add up (or I just don't understand how this works). I see OutOfMemory: max 48MB basically -- I think that's the maximum heap size. Not sure what "total" in this context means, but it looks like about 39MB. It's failing on a 2MB allocation, which I don't really understand why it's failing, there should be 9MB available... What am I misunderstanding here?

Kara
  • 6,115
  • 16
  • 50
  • 57
user645402
  • 737
  • 1
  • 16
  • 34

1 Answers1

4

Welcome to the wonderful world of heap fragmentation. In a nutshell, you need a contiguous chunk of memory to satisfy the allocation, not just enough free bytes.

As an example, imagine an empty 1MB heap. Now imagine that right in the middle of that 1MB is a 1K allocation. Even though you have 99.9% of the space free, you can't allocate anything over about 500K, because it has to be contiguous. Move that 1K allocation around, and you can allocate a lot more, but in pathological cases, you can end up having vastly more free memory than you can allocate.

For your case, I bet if you tried to do 2000 1K allocations it would work great. That would let you know if you are dealing with fragmentation or something else.

twk
  • 16,760
  • 23
  • 73
  • 97
  • so there must be a way to re-configure the fragmented memory. Does a System.gc() do that? – user645402 Jan 24 '12 at 23:00
  • A GC can reduce some fragmentation, but not all memory allocations can be moved. Buffers that are currently being used to call into the operating system for example, cannot be moved. – twk Jan 24 '12 at 23:15
  • so then the other thing is that this thing should support a 48MB heap (at least according to Runtime.maxMemory(), so why doesn't it automatically increase the size of the heap to accomodate the new allocation? – user645402 Jan 24 '12 at 23:21
  • That is an Android limitation: http://stackoverflow.com/questions/5350465/android-heap-size-on-different-phones-and-os-versions – twk Jan 24 '12 at 23:24