24

I'm currently investigating garbage collection problems with my Android app, and I'm curious to know if GC_FOR_ALLOC is indicative of a bigger problem than other GC messages, such as GC_CONCURRENT.

From my understanding, GC_CONCURRENT is doing what the garbage collector should do. The heap has reached a particular limit, better go clean up memory.

GC_FOR_ALLOC suggests to me something more serious is happening if I'm trying to create an object and there's no memory left to do it.

Is there a priority or "seriousness" level for the GC messages?

Andrew Weir
  • 1,020
  • 2
  • 13
  • 27
  • have you read http://stackoverflow.com/questions/895444/java-garbage-collection-log-messages ? the links referred in the accepted answer may help you – kommradHomer Jul 02 '12 at 09:46
  • @kommradHomer Thanks for the response but I don't think that applies here since it is the dalvik virtual machine that would be doing the GC sweep. I still found the link to be an informative, if dense, read. – Andrew Weir Jul 03 '12 at 08:15

1 Answers1

55

In a sense, GC_FOR_ALLOC is more serious than GC_CONCURRENT, because GC_FOR_ALLOC means there were not enough free memory to fulfill an allocation request, so a garbage collection was necessary, whereas GC_CONCURRENT just means that the GC felt like running, typically because the amount of free memory became lower than a certain threshold after an allocation.

A GC_FOR_ALLOC is by itself not a sign of a problem in your application however:

  • Android applications start with a small heap which grows (up to a point) when applications require more and more memory, and a GC_FOR_ALLOC is done before increasing the size of the heap. In this case GC_FOR_ALLOC is perfectly normal.
  • If you allocate memory faster than the concurrent GC has time to free it up, GC_FOR_ALLOC is inevitable. And there's nothing inherently wrong with allocating memory faster than the concurrent GC can free up memory.

A more serious type of GC on Android is GC_BEFORE_OOM, which is performed when an allocation request fails even after GC_FOR_ALLOC and when the application heap has grown as big as it is allowed to be. When this happen, as a last resort, Dalvik will try to release SoftReferences as well, before doing a final attempt at allocating memory and if that fails throw an OutOfMemory exception.

If you're curious to look at the code for this logic, it is in tryMalloc() in dalvik.git/vm/alloc/Heap.cpp

Anyway, if you don't mind, I doubt that looking at logcat output is the most efficient way to debug your garbage collection problems. I don't know what specific problem you are having, but have you looked into tools such as the Allocation Tracker in DDMS and analyzing heap dumps with the help of the hprof-conv tool? (See http://android-developers.blogspot.se/2011/03/memory-analysis-for-android.html for example to get started.)

Martin Nordholts
  • 10,338
  • 2
  • 39
  • 43
  • Thanks for your response. My app has been out in the wild for a while now and we're working on doing some fine tuning to it. One of the big overheads was the GC running up to 30 times within a window of 4 seconds. It just seemed excessive really. With some optimisation, GC runs 6 times now - but FOR_ALLOC is the only call that is being made. But that makes sense now. – Andrew Weir Jul 06 '12 at 15:36