又是一次由於線上報警機制開啓的排查問題之旅。某日,釘釘機器人瘋狂報警:
java
接着就是申請機器權限去排查問題,既然是頻繁Full GC,那咱們排查問題的思路就應該是找到引發Full GC的緣由。引發頻繁Full GC的常見緣由有這麼幾點:git
gc日誌永遠都是咱們排查gc問題最好的工具,因此強烈建議你們在線上配置-XX:+PrintGCDetails -Xloggc:/data/logs/gc.log方便咱們去定位問題。因爲當前項目沒有配置,只好用jstat -gccause去監測,博主監測了五分鐘左右,獲得以下信息:新生代、老年代、元空間內存還不少,FGC漲了9次,而且對應的LGCC都顯示爲System.gc.因爲虛擬機參數並無去配置-XX:MaxDirectMemorySize,因此其堆外內存受限於當前物理機內存,故咱們能夠經過top去查看進程佔了多少內存和經過free -m查看空閒內存(固然visualvm的插件和perftools都是查看堆外內存使用狀況很好的工具,不瞭解自行谷歌)。通過內存分析和業務分析以後,初步判定不是堆外內存致使的,而是由項目中有調用System.gc().github
首先對項目全局進行搜索System.gc(),若是沒有查到,那麼就極可能是依賴的jar包裏存在調用,如何在jar包中查找呢?在這裏給你們推薦一款插件Btracegithub地址。BTrace是Java的安全可靠的動態跟蹤工具。 他的工做原理是經過 instrument + asm 來對正在運行的java程序中的class類進行動態加強。說他是安全可靠的,是由於它對正在運行的程序是隻讀的。也就是說,他能夠插入跟蹤語句來檢測和分析運行中的程序,不容許對其進行修改。所以他存在一些限制:數組
根據官方聲明,不恰當的使用Btrace會致使jvm崩潰,因此在上生產環境以前,必定要在本地充分驗證腳本的正確性。Btrace的常見使用場景有:安全
Btrace依賴於JDK,首先要安裝好JDK並配置JDK的環境變量。jvm
1.下載安裝包工具
下載地址:https://github.com/btraceio/btrace/releases/tag/v1.3.11
2.解壓縮
修改目錄權限:
源碼分析
3.配置環境變量
而後source更新環境變量
4.編寫btrace腳本性能
import static com.sun.btrace.BTraceUtils.jstack; import static com.sun.btrace.BTraceUtils.println; import static com.sun.btrace.BTraceUtils.str; import static com.sun.btrace.BTraceUtils.strcat; import static com.sun.btrace.BTraceUtils.timeMillis; import com.sun.btrace.annotations.BTrace; import com.sun.btrace.annotations.Kind; import com.sun.btrace.annotations.Location; import com.sun.btrace.annotations.OnMethod; import com.sun.btrace.annotations.TLS; @BTrace public class MyTest { @OnMethod(clazz = "java.lang.System", method = "gc" ) public static void startMethod(){ println("****************************************"); jstack(); println("****************************************"); } @OnMethod(clazz = "java.lang.System", method = "gc", location = @Location(Kind.RETURN)) public static void endMethod(){ println("========================================="); jstack(); println("========================================="); } }
5.運行btrace
經過jps -l得到進程的pid,而後經過 btrace <pid> <btrace_script> >> gc.txt & 之後臺任務的方式去開啓btrace腳本監聽對應進程,將對應的棧信息保存到gc.txt中。
6.關閉btrace
spa
通過長達一天的監控,終於抓到了對應的調用棧:
緣由是項目中用到了jxl的Workbook來作Excel相關的功能,每次關閉Workbook的時候都會調用System.gc
至此,咱們就已經抓住了致使頻繁Full GC的鬼了,改動方法也特別簡單,在構造WorkBook的時候,將其成員變量WorkbookSettings的成員變量gcDisabled設置爲true便可避免此問題,或者添加vm參數-Djxl.nogc=true(不太推薦).
每次排查問題的時候遇到了不少困難,在總結的時候卻又不知道該說些什麼~.~。特別感謝提供幫助的笨神、阿飛和零度。