Get a log of all GC operations over time:
Every time a GC happens, you get a line in your LogCat.
08-08 16:42:21.998: D/dalvikvm(26942): GC_CONCURRENT freed 773K, 26% free 4739K/6368K, paused 4ms+3ms, total 92ms 08-08 16:42:21.998: D/dalvikvm(26942): WAIT_FOR_CONCURRENT_GC blocked 11ms
I seem to get them for all the applications on my device.
This line contains a lot of interesting statistics about the GC, such as the amount of freed memory, how long the GC took when it happened, and the size of your heap (used / amount).
Since all of these log lines have the tag dalvikvm , you should be able to collect and filter them for a long period of time and analyzed to learn about GC behavior.
GC specific launch analysis:
If you want to analyze what happens in one specific GC operation, the best tool for working is the Eclipse MAT. Eclipse MAT can analyze heap heaps. Take a heap snapshot, wait for the GC (or run it yourself using DDMS), and then take another snapshot.
Eclipse MAT can show you the delta between two snapshots. Please note that you will see both new distributions and those caused by GC decomposition. More information on comparing shots is available here .
Other thoughts:
I'm not sure how much you can learn to analyze the GC process. GC's internal work is an implementation detail. It may change without notice between OS versions / devices / configurations.
I am trying to figure out how to improve the GC latency that you experience. It seems to me that GC usually works when memory conditions are low. This probably happens during new distributions, so the GC can work while your service is active. Perhaps if you use the time when your service is inactive for the GC manually, you can reduce the number of GCs occurring on the critical path to the response to the web request. To try this, I will add a simple background timer and reset when my service becomes active (new request). When the timer is ticking (inactivity for some period of time), I would start System.gc() manually.