Reputation: 1740
Can anyone explain the below Logcat message :
D/dalvikvm(4440): GC_EXTERNAL_ALLOC freed 338K, 47% free 6427K/11911K, external 20418K/22446K, paused 53ms
E/dalvikvm-heap(4440): 2519424-byte external allocation too large for this process.
D/dalvikvm(4440): GC_FOR_MALLOC freed <1K, 47% free 6427K/11911K, external 20398K/22446K, paused 40ms
E/GraphicsJNI(4440): VM won't let us allocate 2519424 bytes
Upvotes: 2
Views: 508
Reputation: 52303
In older versions of Android, certain bits of native framework code would tell the VM about native allocations. This "external allocation" mechanism was an ugly hack introduced so that native allocations would cause the Dalvik VM to do a garbage collection pass.
The basic problem was that the Java-language Bitmap object used native memory for the pixel storage. Because the managed-heap objects were tiny, and the native-heap objects were large, you could allocate tons of Bitmaps without causing a GC. This was causing apps to bloat up and the system to slow down.
So, "external allocations" were introduced. Whenever the pixel storage for a Bitmap was allocated on the native heap, an equal amount of memory was deducted from the managed heap. The idea is that, if your heap is filling up with no-longer-reference bitmaps, you'll run out of managed heap space and the GC will fire.
(Unfortunately the GC can't actually release the native storage -- you need to run a finalizer to do that, and finalizers run in a separate pass after the GC completes. For a while the native objects were also holding on to some additional managed-heap objects, so you'd have to GC + finalize + GC to actually clean everything up.)
My "favorite" part about external allocations is that the API was a simple "increase by N" / "decrease by N", which meant there was no way to associate the native heap with a managed heap object, or check for leaks. Because all of the information about the Bitmap was kept in the native object, you couldn't even guess at how much native storage was needed, so it was impossible to look at an hprof dump and figure out how much memory a Bitmap was actually using.
In Android 3.0 ("Honeycomb") the pixel storage was moved onto the managed heap, and the external allocation mechanism was removed.
So, what the log message in your question means is: some code, probably Bitmap, wanted to allocate 2.5MB of native heap, but that would exceed the VM's external allocation heap limit. You need to figure out what's eating up 20MB of external allocation storage and release some of it.
The only way to get information about external allocations is by watching the event log. A few years back I threw a script together (gclog.py -- was in AOSP dalvik/tools for a while). I have no idea if it will still do anything useful. I talk about how to use it in this old thread.
Upvotes: 3