一、寫在前面
上一篇文章 我們介紹了性能監控的一些命令,包括 jmap (生成堆存儲快照)和 jstack(生成線程快照),事實上,在沒有一些監控工具之前,我們用的最多的也是這兩個命令來進行虛擬機性能的監控調優。但是這兩個命令都有自己不足的地方:
- 使用 jmap 命令,從 Heap Dump 開始,整個 JVM 都是停頓的,幾G 的 Heap 可能產生幾秒的停頓,在生產環境上執行時需要謹慎再謹慎。
- 使用 jstack 命令,ThreadDump 同樣會造成 JVM 停頓,加了 -l 參數,停頓時間更長,在生產環境上執行要謹慎再謹慎。
后來一些監控工具就應運而生,比如 Jconsule、VisualVM 以及收費的 JProfiler 等,這篇文章主要介紹 Java Mission Control。
二、Java Mission Control
Java Mission Control(簡稱 JMC) 是一個用於對 Java 應用程序進行管理、監視、概要分析和故障排除的工具套件,在 JDk7 7u40之后免費自帶,運行 “JAVA_HOME”\bin\jmc.exe 即可運行 JMC。
JMC 的另一個優點就是:采用取樣,而不是傳統的代碼植入技術,對應用性能的影響非常非常小,完全可以開着 JMC 來做壓測(唯一影響可能是 full gc 多了)。
JMC 主要包括兩種功能:
- 實時監控 JVM 運行時的狀態
- Java Flight Recorder 取樣分析
2.1 實時監控
如果是遠程服務器,使用前要開 JMX
-Dcom.sun.management.jmxremote.port=${YOUR PORT}
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=${YOUR HOST/IP}
文件 -> 連接 -> 創建新連接, 填入上面 JMX 參數的 host 和 port
通過“+”按需添加各種統計圖表。
“觸發器” tab 可以根據 CPU、線程等信息,設定一定的閾值,來觸發報警。
“內存” tab 提供 heap 和 GC 的信息。可以關注 GC次數、時間以及隨着 GC 發生 heap 的內存變化情況,以此來調整 jvm 參數。
“線程” tab 可以關注每條線程所占的CPU、死鎖情況以及線程堆棧信息。
2.2 Flight Recorder(取樣分析)
要采用取樣,必須先添加參數:
-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
取樣時間默認 1 分鍾,可自行按需調整,事件設置選為 profiling,然后可以設置取樣 profile 哪些信息,比如:
- 加上對象數量的統計:Java Virtual Machine -> GC -> Detailed -> Object Count/Object Count after GC
- 方法調用采樣的間隔從 10ms 改為 1ms(但不能低於 1ms,否則會影響性能了): Java Virtual Machine -> Profiling -> Method Profiling Sample/Method Sampling Information
- Socket 與 File 采樣, 10ms 太久,但即使改為 1ms 也未必能抓住什么,可以干脆取消掉: Java Application->File Read/FileWrite/Socket Read/Socket Write
然后就開始 Profile,到時間后 Profile 結束,會自動把記錄下載回來,在 JMC 中展示。
從展示信息中,我們大致可以讀到 JVM參數、GC、熱點代碼、對象分配以及線程等詳細信息。
一般來說,盡可能確保以下幾點,你的程序會跑得更快:
- 分配更少的對象
- 盡可能少進行 full gc
- 盡可能少在 TLAB 外分配對象