一、jdk命令列工具

名稱 主要功能
jps JVM Process Status Tool,顯示指定系統內所有HotSpot虛擬機器程序
jstat JVM Statistics Minitoring Tool,用於收集HotSpot虛擬機器各方面的執行資料
jinfo Configuration Info for Java,顯示虛擬機器配置資訊
jmap Memory Map for Java,生成虛擬機器的記憶體轉儲快照(heapdump)檔案
jhat JVM Heap Dump Browser,用於分析heapdump檔案,它會建立一個HTTP/HTML伺服器,讓使用者可以在瀏覽器上檢視分析結果
jstack Stack Trace for Java,顯示虛擬機器的執行緒快照

1、jps:虛擬機器程序狀況工具

jps(JVM Process Status Tool),功能和ps類似:可以列出正在執行的虛擬機器程序,並顯示虛擬機器執行主類(Main Class,main()函式所在的類)的名稱,以及這些程序的本地虛擬機器的唯一ID(LVMID,Local Virtual Machine Identifier)。雖然功能比較單一,但它是使用頻率最高的JDK命令列工具,因為其他JDK工具大多需要輸入它查詢到的LVMID來確定要監控的是哪一個虛擬機器程序。對於本地虛擬機器程序來說,LVMID與作業系統的程序ID(PID,Process Identifier)是一致的,使用Windows的工作管理員或Unix的ps命令也可以查詢到虛擬機器程序的LVMID,但如果使用了多個虛擬機器程序,無法根據程序名稱定位時,那就只能依賴jps命令顯示主類的功能區才能區分了。

jps命令格式
jps [option] [hostid]

jps可以通過RMI協議查詢開啟了RMI服務的遠端虛擬機器程序狀態,hostid為RMI登錄檔中註冊的主機名。jps的其他常用選項見下表

Tables Are
-q 只輸出LVMID,省略主類的名稱
-m 輸出虛擬機器程序啟動時傳遞給主類的main()函式的引數
-l 輸出主類的全名,如果程序執行的是jar包,輸出jar路徑
-v 輸出虛擬機器程序啟動時JVM引數

jstat命令格式:
jstat [option vmid [interval[s|ms] [count]] ]

jstat(JVM Statistics Monitoring Tool)是用於監控虛擬機器各種執行狀態資訊的命令列工具。它可以顯示本地或遠端虛擬機器程序中的類裝載、記憶體、垃圾收集、JIT編譯等執行資料,在沒有GUI影象介面,只提高了純文字控制檯環境的伺服器上,它將是執行期定位虛擬機器效能問題的首選工具。

– VMID與LVMID需要特別說明下:如果是本地虛擬機器程序,VMID和LVMID是一致的,如果是遠端虛擬機器程序,那VMID的格式應當是:[protocol:][//] lvmid [@hostname[:port]/servername]
–引數interval和count代表查詢間隔和次數,如果省略這兩個引數,說明只查詢一次。假設需要每250毫秒查詢一次程序10524垃圾收集狀況,一共查詢5次,那命令列如下:
這裡寫圖片描述
選項option代表這使用者希望查詢的虛擬機器資訊,主要分為3類:類裝載、垃圾收集和執行期編譯狀況,具體選項及作用參見如下:

選項 作用

-class 監視類裝載、解除安裝數量、總空間及類裝載所耗費的時間
-gc 監視Java堆狀況,包括Eden區、2個Survivor區、老年代、永久代等的容量
-gccapacity 監視內容與-gc基本相同,但輸出主要關注Java堆各個區域使用到的最大和最小空間
-gcutil 監視內容與-gc基本相同,但輸出主要關注已使用空間佔總空間的百分比
-gccause 與-gcutil功能一樣,但是會額外輸出導致上一次GC產生的原因
-gcnew 監視新生代GC的狀況
-gcnewcapacity 監視內容與-gcnew基本相同,輸出主要關注使用到的最大和最小空間
-gcold 監視老年代GC的狀況
-gcoldcapacity 監視內容與——gcold基本相同,輸出主要關注使用到的最大和最小空間
-gcpermcapacity 輸出永久代使用到的最大和最小空間
-compiler 輸出JIT編譯器編譯過的方法、耗時等資訊
-printcompilation 輸出已經被JIT編譯的方法

舉個例子:

C:\Users\Administrator>jstat -gcutil 5828
S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT  
0.00   0.00   1.82  52.18  99.91    329    4.894   269   80.244   85.139

這是我監控到我的eclipse的記憶體狀況。查詢結果表明:新生代Eden區(E,表示Eden)使用了1.82%的空間,兩個Survivor區(S0、S1,表示Survivor0、Survivor1)裡面都是空的,老年代(O,表示Old)和永久代(P,表示Permanent)則分別使用了52.18%和99.91%的空間。程式執行以來共發生Minor GC(YGC,Young GC)329次,總耗時(YGCT,Young GC Time)4.894秒,發生Full GC(FGC)269次,總耗時(FGCT)80.244秒,所有GC總耗時(GCT)85.139秒。
使用jstat工具在純文字狀態下監視虛擬機器狀態的變化,確實不如後面將會提到的VisualVM等視覺化的監視工具直接以圖表展現的那樣直觀。但很多伺服器管理員都習慣了在文字控制檯共組哦,直接在控制檯中使用jstat命令已然是一種常用 的監控方式

3、jinfo: Java配置資訊工具

jinfo(Configuration Info for Java)的作用是實時地檢視和調整虛擬機器的各項引數。使用jps的命令的-v引數可以檢視虛擬機器啟動時顯示指定的引數列表,但如果想知道未被顯示指定的引數的系統預設值,除了去找資料外,就只能使用jinfo的-flag選項進行查詢了(如果只限於JDK1.6或以上版本的話,使用java -XX:+PrintFlagsFinal檢視引數預設值也是一個很好的選擇),jinfo還可以使用-sysprops選項把虛擬機器程序的System.getProperties()的內容打印出來。這個命令在JDK1.5時期已經隨著Linux版的JDK釋出,當時只提供了資訊查詢的功能,JDK1.6之後,jinfo在Windows和Linux平臺都有提供,並且加入了執行期修改引數的能力,可以使用-flag[+|-]name或-flag name=valule修改一部分執行期可寫的虛擬機器引數值。JDK1.6中,jinfo對於Windows平臺的功能仍然有較大的限制,只提供了最基本的-flag選項。

jinfo命令格式:
jinfo [option] pid

執行樣例:查詢CMSInitiatingOccupancyFraction引數值。

C:\Users\Administrator>jinfo -flag CMSInitiatingOccupancyFraction 5828 -XX:CMSInitiatingOccupancyFraction=-1

4、jmap: Java記憶體映像工具

jmap(Memory Map for Java)命令用於生產堆轉儲快照(一般稱為heapdump或dump檔案)。如果不使用jmap命令,要向獲取Java堆轉儲快照還有一些比較”暴力“的手段:譬如-XX:+HeapDumpOnOutOfMemoryError引數,可以讓虛擬機器在OOM異常出現之後自動生生成dump檔案,通過-XX:+HeapDumpOnCtrlBreak引數則可以使用[Ctrl]+[Break]鍵讓虛擬機器生成dump檔案,又或者在Linux系統下通過Kill -3命令傳送程序退出訊號”恐嚇“一下虛擬機器,也能拿到dump檔案。 jmap的作用並不僅僅是為了獲取dump檔案,它還可以查詢finalize執行佇列,Java堆和永久代的詳細資訊,如空間使用率、當前用的是那種收集器等。和jinfo命令一樣,jmap有不少功能在Windows平臺下是受限的,除了生成dump檔案的-dump選項和用於檢視每個類的例項、空間佔用統計的-histo選項所有作業系統都提供外,其餘選項只能在Linux/Solaris下使用。

jmap命令格式:
jmap [option] vmid
option選項合法值與具體含義:

選項 作用
-dump 生成Java堆轉儲快照。格式為:-dump:[live,]format=b,file=,其中live子引數說明是否只dump出存活的物件
-finalizerinfo 顯示在F-Queue中等待Finalizer執行緒執行finalize()方法的物件。只在Linux/Solaris平臺下有效
-heap 顯示Java堆詳細資訊,如使用哪種回收器、引數配置、分代狀況等。只在Linux/Solaris平臺下有效
-histo 顯示堆中物件統計資訊,包括類、例項數量和合計容量
-permstat 以ClassLoader為統計口徑顯示永久代記憶體狀態。只在Linux/Solaris平臺下有效
-F 當虛擬機器程序對-dump選項沒有響應時,可使用這個選項強制生成dump快照。只在Linux/Solaris平臺下有效

樣例:
C:\Users\Administrator>jmap -dump:format=b,file=eclipse.bin 5828 Dumping heap to C:\Users\Administrator\eclipse.bin 
... Heap dump file created
這是使用jmap生成一個正在執行的Eclipse的dump快照檔案的例子,5828為jps查詢到的LVMID。

5、jhat:虛擬機器堆轉儲快照分析工具

Sun JDK提供了jhat(JVM Heap Analysis Tool)命令與jmap搭配使用,來分析jmap生成的堆轉儲快照。jhat內建了一個微型的HTTP/HTML伺服器,生成dump檔案的分析結果後,可以在瀏覽器中檢視,不過實事求是地說,在實際工作中,除非真的沒有別的工具可用,否則一般不會去直接使用jhat命令來分析dump檔案,主要原因有二:一是一般不會在部署應用程式的伺服器上直接分析dump檔案,即使可以這樣做,也會盡量將dump檔案拷貝到其他機器上進行分析,因為分析工作時一個耗時且消耗硬體資源的過程,既然都要在其他機器上進行,就沒必要收到命令列工具的限制了。另外一個原因是jhat的分析功能相對來說很簡陋,VisualVM以及專門分析dump檔案的Eclipse Memory Analyzer、IBM HeapAnalyzer等工具,都能實現比jhat更強大更專業的分析功能。

這裡寫圖片描述

“Server is ready.”出現後就可以在瀏覽器中鍵入http://localhost:7000 檢視分析結果了。
分析結果預設以包為單位進行分組顯示,分析記憶體洩露問題主要會使用到其中的”Heap Histogram“(與jmap-hosto功能一樣)與OQL頁籤的功能。前者可以找到記憶體總容量最大的物件,後者是標準的物件查詢語句,使用類似SQL的語法對記憶體中的物件進行查詢統計。

6、jstack: Java堆疊跟蹤工具

jstack(Stack Trace for Java)命令用於生成虛擬機器當前時刻的執行緒快照(一般稱為threaddump或javacore檔案)。執行緒快照就是當前虛擬機器內每一條執行緒正在執行的方法堆疊的集合,生成執行緒快照的主要目的是定位執行緒出現長時間停頓的原因,如執行緒間死鎖、死迴圈、請求外部資源導致的長時間等待等都是導致執行緒長時間停頓的常見原因。執行緒出現停頓的時候通過jstack來檢視各個執行緒的呼叫堆疊,就可以知道沒有響應的執行緒到底在後臺做些什麼事情,或者等待著什麼資源。

jstack命令格式:
jstack [option] vmid

option選項的合法值與具體意義如下:
選項 作用
-F 當正常輸出的請求不被響應時,強制輸出執行緒堆疊
-l 除堆疊外,顯示關於鎖的附加資訊
-m 如果呼叫到本地方法的話,可以顯示C/C++的堆疊

例項(用jstack檢視eclipse執行緒堆疊):
C:\Users\Administrator>jstack -l 5828

執行結果太長,不截取了。
在JDK1.5中,java.lang.Thread類新增了一個getAllStackTraces()方法用於獲取虛擬機器中所有執行緒的StackTraceElement物件。使用這個方法可以簡單的幾行程式碼就完成jstack的大部分功能,在實際專案中不妨呼叫這個方法做個管理員頁面,可以隨時使用瀏覽器來檢視執行緒堆疊,程式碼如下:

<%@ page import="java.util.Map"%>
<html>
<head>
    <title>伺服器執行緒資訊</title>
</head>
<body>
<pre> <%
         for (Map.Entry<Thread,StackTraceElement[]> stackTrace :           Thread.getAllStackTraces().entrySet()) {
            Thread thread = (Thread) stackTrace.getKey();
            StackTraceElement[] stack = (StackTraceElement[]) stackTrace.getValue();
            if (thread.equals(Thread.currentThread())) {
                continue;
            }
            out.print("\n執行緒:" + thread.getName() + "\n");
            for (StackTraceElement element : stack) {
                out.print("\t" + element + "\n");
            }
        }
    %> </pre>
</body>
</html>

二、jdk視覺化工具

1.JConsole

JConsole工具在JDK/bin目錄下,啟動JConsole後,將自動搜尋本機執行的jvm程序,不需要jps命令來查詢指定。雙擊其中一個jvm程序即可開始監控,也可使用“遠端程序”來連線遠端伺服器。

這裡寫圖片描述

進入JConsole主介面,有“概述”、“記憶體”、“執行緒”、“類”、“VM摘要”和”Mbean”六個頁籤:

這裡寫圖片描述

記憶體頁籤相當於jstat命令,用於監視收集器管理的虛擬機器記憶體(Java堆和永久代)變化趨勢,還可在詳細資訊欄觀察全部GC執行的時間及次數。

這裡寫圖片描述

執行緒頁籤

這裡寫圖片描述

最後一個常用頁籤,VM頁籤,可清楚的瞭解顯示指定的JVM引數及堆資訊。

這裡寫圖片描述
2.VisualVM

VisualVM是一個整合多個JDK命令列工具的視覺化工具。VisualVM基於NetBeans平臺開發,它具備了外掛擴充套件功能的特性,通過外掛的擴充套件,可用於顯示虛擬機器程序及程序的配置和環境資訊(jps,jinfo),監視應用程式的CPU、GC、堆、方法區及執行緒的資訊(jstat、jstack)等。VisualVM在JDK/bin目錄下。

這裡寫圖片描述

VisualVM主介面

這裡寫圖片描述

在VisualVM中生成dump檔案:

這裡寫圖片描述

.