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就看楼主本身的取舍了。
相关文章
相关标签/搜索