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就看樓主本身的取捨了。
相關文章
相關標籤/搜索