I don't observe this on my phone. Are you sure you don't have an
application/service running constantly in the background, and that the
foreground application is in fact truly idle (no free-running
threads)?
Every gc comes from a particular process, and the process id is noted
in the log. For example:
D/dalvikvm( 1188): GC freed 27 objects / 1240 bytes in 92ms
This is a gc in process 1188. Running "ps" can tell you what that
process actually is:
$ adb shell ps | grep 1188
app_9 1188 31 92368 11480 ffffffff afe0c824 S android.process.media
It turns out to be the system media service in this case.
If you do this on your device and determine that the unusual gc
activity you see is coming from a system process of some sort, please
go ahead and file a bug for it. Include specific and explicit steps to
reproduce the problem, since without that there's practically no way
we can track down what's gone wrong.
Thanks, and happy new year!
-dan
I followed Dan's advice and it looks like the guilty process that
causes all the GCs is system_server. Based on the huge range of
messages that come with the same pid, I'm guessing that is a message
queue, and is probably running some Runnable that has been passed to
it by various apps? How can I get more info on what it is doing, so
that I know what the guilty app is? The phone gets slower and slower
over the course of a day or so. If I don't reboot daily then within a
couple of days it is almost unusable, taking 10-30 seconds to open an
app, 5-10 seconds to process a keypress, etc. There are tons of
reports on the web of people having the same problem, and the advice
is always: just reboot your phone every day.
I note that there is
watchdog code in Android that is supposed to reboot the phone in the
early hours of the morning if it hasn't been rebooted in a while, but
this code is disabled in the release.
I tried to write an app to
schedule a regular reboot, but even using introspection to call the
native reboot method that is used by the stack did not work (I assume
for a security reason).
As far as events never being lost -- maybe this is not the problem,
but the state machine in the window manager that handles events has
some incorrect logic in it? The example that seems to indicate that
there might be a problem is as follows. My app is pretty simple, it
lets the user draw multiple lines or shapes on the screen, and also
tracks ACTION_UP/ACTION_DOWN so it can keep the line segments
separate. If you keep drawing lines on the screen until you miss an
ACTION_DOWN event, then (with your finger still on the screen) set a
breakpoint at the start of onTouchEvent(), then keep moving your
finger on the screen, you don't actually get any more events fired
until you lift your finger off the screen and then put it back down
again, at which point the code stops at the breakpoint. This is not a
bug with my code, because my code's onTouchEvent method never even
gets called, and it seems that something somewhere got into a weird
state. If you miss the ACTION_UP event, then you don't get another
ACTION_UP until you finish drawing the next line -- the method is
never called with that event. It happens in about 5% of cases right
now (somewhat hard to trigger).
I was still losing events during GCs, but only half as much once I
started using the motion history in motion events. According to
Dianne, these events should never be lost. Is it possible that if
system_server is really being taxed, then the CPU is pegged so hard
that even the responsiveness of lower-level layers of the platform is
impacted?
That would explain the behavior. I just have a simple LinearLayout
with a TextView at the top and a custom canvas View at the bottom. If
the ACTION_DOWN somehow starts sending the motion events to a
different view in the hierarchy, which one would it be? I would
imagine that LinearLayout doesn't normally catch motion events... Is
there a way to debug where events are going?