JVM 发生GC时的事件通知的机制

如果您还在用Java 6的话,请赶紧升级到Java 7吧。 
以下以Java 7为基准来讨论。 

============================================================== 

在Java 7里有两种办法来监听GC事件。 

一种是比较传统的办法,从Java SE 5开始就可用。 
用C或C++或其它native语言来实现一个JVMTI agent,注册监听里面的 GarbageCollectionFinish 事件即可。 
JVMTI提供了GarbageCollectionStart和GarbageCollectionFinish事件,有需要的话前者也可以监听上。这两个事件都是在JVM处于GC暂停阶段之中发出的,此时不能执行任何Java代码。 
可以通过JVMTI的 GetStackTrace 函数来获取当时某个指定的Java线程的栈,或者用 GetAllStackTraces 来获取所有Java线程的栈。 

-------------------------------------------------------------- 

另一种是用Java 7新推出的JMX API的GC notification。用Java代码注册一个NotificationListener来监听GC事件即可。这边的事件是在GC完成之后才发出的。可以配置超时时间,只在超过指定的时间时才发出事件。 
具体用法可参考JavaDoc: GarbageCollectionNotificationInfo  
以及这个bug report里有具体注册GC notification的代码: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7087969  

我以前写过一个跟它的实现机制相关的笔记,有兴趣的话可以参考: https://gist.github.com/rednaxelafx/1465445 。相关邮件讨论: http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2011-August/002352.html  

同样用JMX, ThreadMXBean.dumpAllThreads 可以获取所有Java线程的栈。 

用JMX版虽然可以用Java代码写,挺方便,但它获得GC事件通知时JVM已经不在暂停阶段,所有Java线程都重新变成可运行的,于是此时获取的stack trace就不如JVMTI准确(至少从楼主的意图来看)。用JVMTI还是用JMX就看楼主自己的取舍了。

你可能感兴趣的:(jvm,GC)