前言
服務器
定位系統問題的時候,知識、經驗是基礎,數據是依據,工具是運用知識處理數據的手段。這裏說的數據包括:運行日誌、異常堆棧、GC日誌、線程快照、堆轉儲快照等。常用適當的虛擬機監控和分析的工具能夠加快分析數據、定位解決問題的速度。函數
jps:虛擬機進程情況工具工具
首先約定一下運行的代碼都是如下這段性能
1 public class TestMain 2 { 3 public static void main(String[] args) 4 { 5 while (true) 6 { 7 8 } 9 } 10 }
JDK的不少小工具的名字都參考了UNIX命令的命名方式,jps(JVM Process Status)是其中的典型。除了名字像UNIX的ps命令外,它的功能也和ps命令相似:能夠列出正在運行的虛擬機進程,並顯示虛擬機執行主類名稱以及這些進程的本地虛擬機惟一ID(Local Virtual Machine Identifier,LVMID)。雖然功能比較單一,但它是使用最高的JDK命令行工具,由於其餘的JDK工具大多須要輸入它查詢到的LVMID來肯定要監控的是哪個虛擬機進程。spa
jps命令格式:操作系統
jps [ options ] [ hostid ]命令行
jps工具主要選項
線程
選 項 | 做 用 |
-q | 只輸出LVMID,省略主類的名稱 |
-m | 輸出虛擬機進程啓動時傳遞給主類main()函數的參數 |
-l | 輸出主類的全名,若是進程執行的是jar包,輸出jar包路徑 |
-v | 輸出虛擬機進程啓動時的JVM參數 |
jps執行樣例3d
某個虛擬機進程執行TestMain這個類的main方法,看到10492就是該虛擬機進程的ID日誌
jstat:虛擬機統計信息監控工具
jstat(JVM Statistics Monitoring Tool)使用於監視虛擬機各類運行狀態信息的命令行工具。它能夠顯示本地或者遠程(須要遠程主機提供RMI支持)虛擬機進程中的類信息、內存、垃圾收集、JIT編譯等運行數據,在沒有GUI,只提供了純文本控制檯環境的服務器上,它將是運行期間定位虛擬機性能問題的首選工具。
jstat命令格式
jstat [ option vmid [ interval [ s | ms ] [ count ] ] ]
這個VMID,對於本地虛擬機進程而言,VMID和LVMID是一致的。參數interval和count分別表示查詢間隔和次數,若是省略這兩個參數,說明只查詢一次,假設須要每250毫秒查詢一次進程2764的垃圾收集狀況,一共查詢20次,那命令應當是:
jstat -gc 2764 250 20
jstat主要工具選項
選 項 | 做 用 |
-class | 監視類裝載、卸載數量、總空間以及類裝載所耗費的時間 |
-gc | 監視Java堆情況,包括Eden區、兩個Survivor區、、老年代、永久帶等的容量、已用空間、GC時間合計等信息 |
-gccapacity | 監視內容基本與-gc相同,但輸出主要關注Java堆各個區域使用到的最大、最小空間 |
-gcutil | 監視內容基本與-gc相同,但輸出主要關注已使用的空間佔總空間的百分比 |
-gccause | 與-gcutil功能同樣,可是會額外輸出致使上一次GC產生的緣由 |
-gcnew | 監視新生代GC情況 |
-gcnewcapacity | 監視內容基本與-gcnew相同,但輸出主要關注使用到的最大、最小空間 |
-gcold | 監視老年代GC情況 |
-gcoldcapacity | 監視內容基本與-gcold相同,但輸出主要關注使用到的最大、最小空間 |
-gcpermcapacity | 輸出永久代使用到的最大、最小空間 |
-compiler | 輸出JIT編譯器編譯過的方法、耗時等信息 |
-printcompilation | 輸出已經被JIT編譯的方法 |
jstat執行樣例
jstat監視選項衆多,舉一個例子來查看一下該命令如何查看監視結果
查詢結果代表,新生代Eden區(E,表示Eden)使用了2%的空間,兩個Survivor區(S0、S1,表示Survivor0、Survivor1)都是空的,老年代(O,表示Old)和永久帶(P。表示Permanent)則分別使用了0%和13.84%的空間。程序運行以來共發生Minor GC(YGC,表示Young GC)0次,總共耗時0秒;發生Full GC(FGC,表示Full GC)3次,Full GC共耗時(FGCT,Full GC Time)爲0秒,全部GC總耗時(GCT,表示GC Time)0秒。
jinfo:Java配置信息工具
jinfo(Configuration Info for Java)的做用是實時地查看和調整虛擬機各項參數。使用jps命令的-v能夠查看虛擬機啓動時顯式指定的參數列表,但若是想知道未被顯式指定的參數的系統默認值,可使用jinfo的-flag選項進行查詢,jinfo還可使用-sysprops選項把虛擬機進程的System.getProperties()的內容打印出來。
jinfo命令格式
jinfo [ option ] pid
jinfo執行樣例
jinfo這個命令對於Windows平臺有較大限制,在Linux和Solaris系統才能夠正常使用,因此這裏就不演示了。
jmap:Java內存映像工具
jmap(Memory Map for Java)命令用於生成堆轉儲快照。若是不使用jmap命令,要想獲取Java堆轉儲,可使用「-XX:+HeapDumpOnOutOfMemoryError」參數,可讓虛擬機在OOM異常出現以後自動生成dump文件,Linux命令下能夠經過kill -3發送進程退出信號也能拿到dump文件。
jmap的做用並不只僅是爲了獲取dump文件,它還能夠查詢finalize執行隊列、Java堆和永久代的詳細信息,如空間使用率、當前使用的是哪一種收集器等。和jinfo同樣,jmap有很多功能在Windows平臺下也是受限制的,除了生成dump文件的-dump選項和用於查看每一個類的實例、空間佔用統計的-histo選項在全部操做系統都提供以外,其他選項都只能在Linux和Solaris系統下使用。
jmap命令格式
jmap [ option ] vmid
jmap工具主要選項
選 項 |
做 用 |
-dump | 生成Java堆轉儲快照。格式爲-dump:[live, ]format=b,file=<filename>,其中live自參數說明是否只dump出存活的對象 |
-finalizerinfo | 顯示在F-Queue中等待Finalizer線程執行finalize方法的對象。只在Linux和Solaris系統下有效 |
-heap | 顯示Java堆詳細信息,如使用哪一種收集器、參數配置、分代情況等。只在Linux和Solaris系統下有效 |
-histo | 顯示堆中對象統計信息,包括類、實例數量、合計容量 |
-permstat | 以ClassLoader爲統計口徑顯示永久代內存狀態。只在Linux和Solaris系統下有效 |
-F | 當虛擬機進行對-dump選項沒有響應時,可以使用這個選項強制生成dump快照。只在Linux和Solaris系統下有效 |
jmap執行樣例
一樣,這個命令對Window環境限制也比較大,就不演示了。
jstack:Java堆棧跟蹤工具
jstack(Stack Trace for Java)命令用於生成虛擬機當前時刻的線程快照。線程快照就是當前虛擬機內每一條線程正在執行的方法堆棧的集合,生成線程快照的目的主要是定位線程長時間出現停頓的緣由,如線程間死鎖、死循環、請求外部資源致使的長時間等待等都是致使線程長時間停頓的緣由。線程出現停頓的時候經過jstack來查看各個線程的調用堆棧,就能夠知道沒有響應的線程到底在後臺作些什麼事情,或者在等待些什麼資源。
jstack命令格式
jstack [ option ] vmid
jstack主要工具選項
選 項 | 做 用 |
-F | 當正常輸出的請求不被響應時,強制輸出線程堆棧 |
-l | 除堆棧外,顯示關於鎖的附加信息 |
-m | 若是調用到本地方法的時候,能夠顯示C/C++的堆棧 |
jstack執行樣例
只截取一部分,看到這就是10492這個虛擬機進程ID當前時刻的線程快照。線程處於RUNNABLE狀態,執行到了TestMain函數的第7行,而且一直停留在第7行。
其餘
上面都是利用命令採集指定進程的虛擬機運行時的信息,實際上,還能夠利用可視化工具對指定PID的虛擬機運行時信息進行監控,這裏推薦兩個:
一、JConsole
在Java_HOME/bin目錄下,有一個jconsole.exe,雙擊運行一下就能夠了。
二、Visual VM
這個是到目前爲止隨JDK發佈的功能最爲強大的運行監視和故障處理工具,除了最基本的運行監視、 故障處理外,還有性能分析的功能,且十分強大。Visual VM還有一個很大的優勢,它對應用程序的實際性能影響很小,使得它能夠直接應用在生產環境中。
至於具體如何使用,就不演示了,比較簡單。除了上面兩個工具,還可使用JProfiler、YourKit等專業且收費的Profiling工具。