I am instru开发者_C百科menting the Dalvik VM and would like to know if there are any tools to analyze garbage collection in dalvik. I know about allocation tracker but I'm looking for something more elaborate.
Get a log of all GC operations over time:
Every time a GC takes place, 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
It seems I'm getting those for all apps on my device.
This line includes lots of interesting stats about the GC like the amount of memory freed, how long the GC took, when exactly did it happen and the size of your heap (used/total).
Since all of those log lines have the tag dalvikvm
, you should be able to collect and filter them over a long period of time and analyze to learn about GC behavior.
Analyzing a specific run of the GC:
If you want to analyze what happens in one specific GC operation, the best tool for the job is Eclipse MAT. Eclipse MAT can parse heap dumps. Take a heap snapshot, wait for the GC (or trigger it yourself using DDMS), and then take another snapshot.
Eclipse MAT can show you the delta between the two snapshots. Notice you'll see both new allocations and GC-caused deallocations. More info about comparing snapshots is available here.
Some other thoughts:
I'm not sure how much you would be able to learn from analyzing the GC process. The inner workings of the GC are an implementation detail. It can change without notice between OS versions / devices / configurations.
I'm trying to think of ways to improve the GC latency you're experiencing.. It seems to me the GC usually runs when memory conditions are low. This probably happens during new allocations, therefore the GC might be running while your service is active. Maybe, if you use the time your service is inactive to GC manually, you would be able to reduce the number of GC's happening in the critical path of responding to a web request. To try that, I would add a simple background timer, and reset it whenever my service becomes active (new request). When the timer ticks (inactivity for some period of time), I would run System.gc()
manually.
精彩评论