I\'d like to register a callback with the JVM so I know when garbage collection is happening. Is there any way to do this?
EDIT: I want to do this so I can log out
As of Java7u4, you can get notifications from the GarbageCollectorMXBean. See http://docs.oracle.com/javase/7/docs/jre/api/management/extension/com/sun/management/GarbageCollectionNotificationInfo.html
Another use case for getting impending GC notifications: if your app is load balanced then you can then notify the load balancer to take your node out of the pool when a GC is about to start to that it does not receive requests that would have to wait for a full GC to get dealt with.
That doesn't help in-flight requests that arrived just before the GC kicked in but, in my case at least, most requests are subsecond and major GCs are 5-10s, every few minutes. We can tweak the NewGen ratios etc but the general point still applies: major GC may be much longer than typical response times so you may want to premptively stop a node starting a major GC from receiving requests.
When GC is over, a thread in the JVM can send a notification to the load balancer to let it know its back in business or the LB can rely on its usual keepalive.
There's an interesting article on Javalobby discussing one method of doing this.
If you're looking at this as a diagnostic tool, I recommend redirecting your application log to StdOut and then redirecting both StdOut and StdErr into a file. This will give you the detail of JVM logging, without forcing you to change your application code.
I think that the standard way is to use the JVM Tool Interface (JVM TI) to write an agent with a GC start callback and to log the time from it (see GetTime). Note that a Garbage Collection Start event is sent for full GCs only.
Sample JVM TI agents is available in the demo directory of the JDK 5.0 or the JDK 6 download. The tech article The JVM Tool Interface (JVM TI): How VM Agents Work is another very good resource. Also have a look at Creating a Debugging and Profiling Agent with JVMTI.