Android logs 'GC_EXTERNAL_ALLOC' 'GC_FOR_MALLOC' - android

While running my apps, I have got this kind of logs:
GC_EXTERNAL_ALLOC freed 2K, 38% free 8772K/14087K, external 17480K/17998K, paused 87ms
GC_FOR_MALLOC freed 0K, 38% free 8772K/14087K, external 17480K/17998K, paused 67ms
GC_CONCURRENT freed 2125K, 47% free 6214K/11719K, external 7142K/8400K, paused 3ms+5ms
Does anyone know what these logs mean? Thanks in advance!
What is the difference between 'GC_EXTERNAL_ALLOC', 'GC_FOR_MALLOC' and 'GC_CONCURRENT'. Are there some other 'GC' events?
What does '38% free 8772K/14087K' mean? What is '8772K' and what is '14087K'?
What does 'external 17480K/17998K' mean? What is '17480K' and what is '17998K'?
Thanks!

Another place where the Dalvik garbage collector messages are explained is in this video: Google I/O 2011: Memory management for Android Apps
At about 14 minutes into the presentation, he breaks down the message format. (BTW, that video has really good info on debugging memory leaks)
Roughly speaking, the format is [Reason] [Amount Freed], [Heap Statistics], [External Memory Statistics], [Pause Time]
Reason
Viktor/Robert already explained GC_CONCURRENT, GC_FOR_MALLOC, GC_EXTERNAL_ALLOC.
There is also:
GC_HPROF_DUMP_HEAP - If you dump heap by clicking the "dump heap" button from DDMS or programatically
GC_EXPLICIT - If you call System.gc()
Amount Freed
E.g. freed 2125K
Self explanatory
Heap Statistics
E.g. 47% free 6214K/11719K
These numbers reflect conditions after the GC ran. The "47% free" and 6214K reflect the current heap usage. The 11719K represents the total heap size. From what I can tell, the heap can grow/shrink, so you will not necessarily have an OutOfMemoryError if you hit this limit.
External Memory Statistics
E.g external 7142K/8400K
Note: This might only exist in pre-Honeycomb versions of Android (pre 3.0).
Before Honeycomb, bitmaps are allocated external to your VM (e.g. Bitmap.createBitmap() allocates the bitmap externally and only allocates a few dozen bytes on your local heap). Other examples of external allocations are for java.nio.ByteBuffers.
Pause Time
If it's a concurrent GC event, there will be two times listed. One is for a pause before the GC, one is for a pause when the GC is mostly done.
E.g. paused 3ms+5ms
For non-concurrent GC events, there is only one pause time and it's typically much bigger.
E.g. paused 87ms

I was also looking for this information.
GC stands for garbage-collector, which collects unused objects during runtime of your app.
GC_EXTERNAL_ALLOC: Means that the VM is trying to reduce the amount of memory used collectable objects, to make room for non-collectable objects.
GC_FOR_MALLOC: Means that the GC was triggered because there wasn't enough memory left on the heap to perform an allocation. Might be triggered when new objects are being created.
GC_CONCURRENT: Triggered when the heap has reached a certain amount of objects to collect.
I am guessing that the 38% free means that 38% of the heap is unused. 8772K would be the size of the used memory on the heap and 14087K would be the size of the heap.
I don´t know, sorry.
Please note that all of this information is based on a post from Robert on a similiar question posted here on stackoverflow. All credit (as long as this is correct) goes to Robert.

Related

Understand the Garbage collector logs flutter

Here is the output of my logging of my flutter app :
Explicit concurrent copying GC freed 25188(844KB) AllocSpace objects, 1(20KB) LOS objects, 2% free, 301MB/309MB, paused 348us total 317.699ms
I would like to understand :
What does "LOS" mean ?
What is the "2% free" ? (The space that the garbage collector managed to free ? or the remaining RAM available ?)
What represents the 301MB and the 309MB ?
As i am using the flutter DevTools to look for memory, i am seeing very different numbers :
’
I have added the "Android" tag because i am running the app on Android 10 and i believe the answer would be the same for IOS.
Thanks in advance
This log messages are not coming from Flutter but Android itself. Based on the log format in your example I guess it is logging from ART (Android RunTime) and where the log format is described in details here the documentation: https://developer.android.com/studio/debug/am-logcat?hl=lt#ARTLogMessages
So to answer your questions:
What does "LOS" mean ?
Large Object Space
What is the "2% free" ? (The space that the garbage collector managed to free ? or the remaining RAM available ?). What represents the 301MB and the 309MB ?
From the linked documentation:
Heap stats
Percentage free and (number of live objects)/(total heap size).
So your current heap takes 309 MB memory, contains objects which takes 301 MB inside it. Which means 2% of the heap is free to be used.

android - GC_FOR_ALLOC freed 6346K, 7% free , paused 143ms, total 143ms

I'm developing an offline mapView using OSMdroid Library. My tilesource loads the tiles but renders quit steadily. But the fact is in my log messages, I keep getting this error:
GC_FOR_ALLOC freed 6346K, 7% free , paused 143ms, total 143ms
I'm not sure how to debug this? Any ideas, do I have any memory leaks?
This is not an error, but an information that Garbage collector has run.
If you are seeing a lot of those, it might mean that you are making many allocations or have little memory. You should try to improve your program's memory performance.
There is a good source information about investigating RAM consumption in Android:
https://developer.android.com/tools/debugging/debugging-memory.html
There is also a document about general strategies for managing your memory consumption in Android:
http://developer.android.com/training/articles/memory.html

Defrag/decrease heap size on pre honeycomb

I developed an app that on startup parses some pretty big amounts of JSON which causes the heap to grow close to its limit. A little later the app is loading several bitmaps. On Honeycomb and above devices, which seem to be using the same memory region for bitmap allocations as well as Java object allocations, this isn't causing any issues as the memory needed for JSON parsing has been freed by then. However on pre-Honeycomb devices it causes OutOfMemoryErrors
As the heap size never goes down dalvik seems to not be able to grow the memory reserved for external allocations (e.g. bitmaps).
This is one example log output for a crash
GC_EXTERNAL_ALLOC freed 601K, 81% free 5504K/27591K, external 4809K/5561K, paused 58ms
586224-byte external allocation too large for this process.
As you can see there is plenty of memory available on the heap but not much for external allocation.
Is there a way I can force dalvik to defrag and shrink the heap? Or can I force bitmap allocations to happen on the heap instead of memory reserved for external allocations? Or is there any other approach to this problem I'm missing out on?
** UPDATE **
Here is more log output (the specific device doesn't log dalvik-heap messages):
On startup when the JSON gets parsed the dalvik heap grows:
GC_CONCURRENT freed 800K, 19% free 12717K/15687K, external 2637K/2773K, paused 2ms+5ms
GC_CONCURRENT freed 871K, 19% free 13857K/16903K, external 2637K/2773K, paused 2ms+5ms
GC_CONCURRENT freed 1106K, 19% free 14766K/18055K, external 2637K/2773K, paused 3ms+5ms
GC_CONCURRENT freed 818K, 16% free 15946K/18951K, external 2637K/2773K, paused 3ms+6ms
GC_CONCURRENT freed 825K, 15% free 17151K/20167K, external 2637K/2773K, paused 2ms+6ms
GC_CONCURRENT freed 830K, 15% free 18356K/21383K, external 2637K/2773K, paused 2ms+5ms
GC_CONCURRENT freed 814K, 14% free 19519K/22535K, external 2637K/2773K, paused 2ms+6ms
GC_CONCURRENT freed 823K, 13% free 20720K/23751K, external 2637K/2773K, paused 2ms+5ms
GC_CONCURRENT freed 814K, 13% free 21873K/24903K, external 2637K/2773K, paused 3ms+6ms
GC_CONCURRENT freed 813K, 12% free 23016K/26055K, external 2637K/2773K, paused 2ms+5ms
GC_CONCURRENT freed 1771K, 15% free 23205K/27207K, external 2637K/2773K, paused 2ms+5ms
After that's done most of the heap gets freed again successfully:
GC_EXPLICIT freed 19207K, 83% free 4735K/27207K, external 2736K/2773K, paused 140ms
At this point I have 20 MB free Dalvik heap space and start allocating bitmaps a little later:
GC_EXTERNAL_ALLOC freed 254K, 83% free 4814K/27207K, external 2771K/2773K, paused 47ms
GC_EXTERNAL_ALLOC freed 721K, 83% free 4880K/27207K, external 3881K/4131K, paused 50ms
GC_EXTERNAL_ALLOC freed 235K, 83% free 4870K/27207K, external 5398K/5561K, paused 62ms
Total device limit seems to be 32 MB the dalvik heap takes 27 MB of those and never goes down so I run out of external memory space to alloc bitmaps.
I want to try and tackle this from a completely different perspective. Memory trouble on Android = the damn native heap and bitmaps 90% of the time.. But this doesn't add up here. As far as I recall, the native heap has very little limitations and can grow as much as it wants. The only limitation I recall is a manual test in the dalvik GC that makes sure your used dalvik heap plus your used native heap don't surpass your app heap limit.
What if your troubles are not related to the native heap - only your dalvik heap.
I assumed that your failing 500kb allocation is in the native heap (for the bitmap pixels). There's a chance this allocation is actually in your dalvik heap. Since your heap is so fragmented, the system cannot find a continuous 500kb chunk in your dalvik heap and you crash.
Which bitmap decoding function are you using? Some methods decode directly from a resource to the native heap and some methods (like the ones using a byte array), are decoding from buffers on the dalvik heap which would explain a big allocation there.
To fix this either change your bitmap decoding function and make sure it doesn't allocate on the dalvik heap at all, or better yet, let's fix your entire fragmentation problem at the source.
Here are some ideas to work around fragmentation issues in general (apply these during your JSON handling part in the beginning):
Run System.gc() manually in strategically placed locations. Popular locations are during destruction of large objects like activity onDestroy. Or whenever you finish with a large JSON chunk, throw a manual GC in there.
Assist the System GC free resources faster. This will prevent your heap from becoming fragmented in the first place. Plenty of material on the net on how to do that. Some from the top of my head:
If you have frequent small allocations, try to adopt a memory reuse scheme like making a pool of objects, and reusing objects in the pool instead of allocating new ones. This optimization is often seen in android adapters (like view reuse in listviews)
Manually set variables to null when you don't need them in order to explicitly disconnect them from the reference graph and mark them for easy GC (same goes for explicitly clearing data collections)
Avoid immutable classes when you have plenty of operations, like concatenation of strings, use StringBuilder instead of regular Strings
Avoid finalizers completely
Avoid circular references, or at least change one of them to a weak reference
Use weak references in general where they're needed
You can measure how successful you are by making sure your heap does not grow to huge sizes when you're only using a small part of it
First of all, are you running on the emulator? Because your heap size seems a bit too small. From my calculation you're crashing after about a total of 11MB total use (dalvik+native) and that's very little. Just to verify, do you have a line similar to this after your crash?
08-22 18:16:24.209: I/dalvikvm-heap(471): Clamp target GC heap from 24.610MB to 24.000MB
The max heap size (dalvik+native) is different between devices. The minimum is 16MB and the larger your screen resolution, the larger it is. Devices of 480x800 normally have above 32MB. You can control the heap size in your AVD settings of the emulator, make sure it's big enough to reflect a real device.
Regarding your question, you're not supposed to defray the heap yourself. The VM does that automatically. It is true that the whole native heap mess makes it harder for the GC to estimate problems so you'll get a few OutOfMemoryErrors which you can probably avoid by manually running the GC before large allocations.
More specifically, your large allocations happen when bitmaps are parsed (during calls like BitmapFactory.decodeXXX()). From my experience it actually helps to run System.gc() before them. You only need to do this on pre Honeycomb devices.
Another tip is to free the native allocations as soon as possible. The pixels of your bitmaps are found in the native heap. They are freed only on the bitmaps finalizer, which as you know takes ages to run. This memory will only be freed after several runs of the system GC. This is why it's recommended to free it yourself manually. As soon as you're done with any bitmap, call Bitmap.recycle() to free its native memory immediately.

I want to Understand Android Log

is any one know what is the meaning this LOG test
it display every time when i do any operation in my APP
TEXT
09-06 17:41:30.194: D/dalvikvm(4900): GC_CONCURRENT freed 440K, 49% free 3317K/6471K, external 0K/512K, paused 4ms+7ms
dos it related to memory allocation ?
GC_CONCURRENT
Means that Garbage Collection happens in a parallel manner. Without affecting any performance.
freed 440K
This particular cycle of GC has freed 440k memory.
free 3317K/6471K
Available and total Heap Memory Details.
external 0K/512K
External Memory available for your app(other than heap).
4ms+7ms
4ms at the beginning of GC was paused and at the end 7ms was consumed by GC.
That is, during this GC, all your activities were suspended for a total of 11ms , 4ms at the beginning and 7ms at the end.
For more info on this, please watch this video. He explains this very clearly.
Patrick Dubroy Memory Management
Indeed. It shows that garbage colector was fired ( which happens on regular basis) and it could reclaim 440K of memory. Whether it is a lot or not depends on your application, but less is better. Rule of thumb is to avoid memory allocation whenever possible.

What do GC_FOR_MALLOC, GC_EXPLICIT, and other GC_* mean in Android Logcat?

If you see the Android logs, you may see a lot of those things.
What do they mean, knowing those may help us doing better memory allocations.
Example:
28470 dalvikvm D GC_FOR_MALLOC freed 665 objects / 239992 bytes in 71ms
28470 dalvikvm D GC_FOR_MALLOC freed 673 objects / 240288 bytes in 87ms
21940 dalvikvm D GC_EXPLICIT freed 4802 objects / 185320 bytes in 78ms
28470 dalvikvm D GC_FOR_MALLOC freed 666 objects / 240536 bytes in 63ms
GC_FOR_MALLOC means that the GC was triggered because there wasn't enough memory left on the heap to perform an allocation. Might be triggered when new objects are being created.
GC_EXPLICIT means that the garbage collector has been explicitly asked to collect, instead of being triggered by high water marks in the heap. Happens all over the place, but most likely when a thread is being killed or when a binder communication is taken down.
There are a few others as well:
GC_CONCURRENT Triggered when the heap has reached a certain amount of objects to collect.
GC_EXTERNAL_ALLOC means that the the VM is trying to reduce the amount of memory used for collectable objects, to make room for more non-collectable.
Update: There has been a name-change of the first event in later versions of Android. It's now called "GC_FOR_ALLOC".
There is also a new event available, although very rare in modern phones:
GC_BEFORE_OOM means that the system is running really low on memory, and that there is a final GC performed, in order to avoid calling the low memory killer.
Another place where the Dalvik garbage collector messages are explained is in this video: Google I/O 2011: Memory management for Android Apps
At about 14 minutes into the presentation, he breaks down the message format. (BTW, that video has really good info on debugging memory leaks)
Roughly speaking, the format is [Reason] [Amount Freed], [Heap Statistics], [External Memory Statistics], [Pause Time]
Reason
Robert/yuku already gave info on the meaning of these.
Amount Freed
E.g. freed 2125K
Self explanatory
Heap Statistics
E.g. 47% free 6214K/11719K
These numbers reflect conditions after the GC ran. The "47% free" and 6214K reflect the current heap usage. The 11719K represents the total heap size. From what I can tell, the heap can grow/shrink, so you will not necessarily have an OutOfMemoryError if you hit this limit.
External Memory Statistics
E.g external 7142K/8400K
Note: This might only exist in pre-Honeycomb versions of Android (pre 3.0).
Before Honeycomb, bitmaps are allocated external to your VM (e.g. Bitmap.createBitmap() allocates the bitmap externally and only allocates a few dozen bytes on your local heap). Other examples of external allocations are for java.nio.ByteBuffers.
Pause Time
If it's a concurrent GC event, there will be two times listed. One is for a pause before the GC, one is for a pause when the GC is mostly done.
E.g. paused 3ms+5ms
For non-concurrent GC events, there is only one pause time and it's typically much bigger.
E.g. paused 87ms
I also found this in the Android sources, dalvik/vm/alloc/Heap.h. May this be useful.
typedef enum {
/* Not enough space for an "ordinary" Object to be allocated. */
GC_FOR_MALLOC,
/* Automatic GC triggered by exceeding a heap occupancy threshold. */
GC_CONCURRENT,
/* Explicit GC via Runtime.gc(), VMRuntime.gc(), or SIGUSR1. */
GC_EXPLICIT,
/* GC to try to reduce heap footprint to allow more non-GC'ed memory. */
GC_EXTERNAL_ALLOC,
/* GC to dump heap contents to a file, only used under WITH_HPROF */
GC_HPROF_DUMP_HEAP
} GcReason;

Categories

Resources