JVM性能監控與故障處理工具

引言

在 應用服務出現模型的卡頓或者CPU飆升等問題時,總是要分析一下對應的進程的JVM狀態以定位問題和解決問題並做出響應的優化,在這個過程中java自帶的一些狀態監控 命令工具就非常方便了。

 

1、jps:JVM進程狀況工具

JDK中很多的小工具都參考 了unix的命名方式,jps 就是其中的典型。除了名稱和UNIX中的ps相似之外,功能也和ps命令類似:可以列出正在運行的虛擬機進程,並顯示虛擬機執行主類( main class,main()函數所在類)名稱及這些進程的 本地虛擬機唯一id。

命令格式:

jps [options] [hostid]

options參數解釋:

  • -l:輸出主類全名或jar 路
  • -q:只輸出LVMD(Local Virtual Machine Identifier , LVMID)
  • -m:輸出JVM啓動時傳遞給main()的參數
  • -v:輸出JVM啓動時顯示指定的JVM參數

jps執行樣例:

2、jstat:JVM統計信息監控工具

jstat命令式使用比較頻繁的命令,主要用來顯示 本地或者遠程虛擬機中類裝載、內存、垃圾收集、JIT編譯等運行數據。 在沒有GUI圖形界面,只提供了純文本的控制檯環境的服務器上,它將是運行期間定位虛擬機性能問題的首選工具。

命令格式:

jstat  [option]  LVMID  [interval ] [count]

其中LVMID是進程id,interval是打印間隔時間(毫秒),count是打印次數,如果省略這兩個參數,說明只查詢一次。

option參數解釋:

選項 作用
-class 監視類裝載,類卸載,總空間及類裝載所消耗的時間
-gc 監視java堆狀況,包括Eden區,兩個survivor區,老年代,永久代等容量、已經使用空間、GC時間合計信息
-gcutil 監視內容與-gc基本相同,但是輸出主要關注已使用空間站總空間的百分比
-gccapacity 監視內容與-gc基本相同,但是輸出主要關注java堆各個區域使用到的最大、最小空間
-gccause 與-gcutil功能一樣,但是會額外輸出導致上一次GC產生的原因
-gcnew 監視新生代的GC狀況
-gcnewcapacity 監視內容與-gcnew基本相同,輸出主要關注使用到的最大最小空間
-gcold 監視老年代GC狀況
-gcoldcapacity

監視內容與-gcold基本相同,輸出主要關注使用到的最大、最小空間

-gcpermcapacity 輸出永久代使用到的最大、最小空間
-compiler 輸出JIT編譯器編譯過的方法、耗時等信息
-printcompilation 輸出已經被JIT編譯的方法

例如需要 每250秒查詢一次進程3900垃圾收集狀況,一共查詢20次,執行命令如下:

jstat -gc 3900 250 20

字段解釋:

  • S0C survivor0大小
  • S1C survivor1大小
  • S0U survivor0已使用大小
  • S1U survivor1已使用大小
  • EC Eden區大小
  • EU Eden區已使用大小
  • OC 老年代大小
  • OU 老年代已使用大小
  • MC 方法區大小
  • MU 方法區已使用大小
  • CCSC 壓縮類空間大小
  • CCSU 壓縮類空間已使用大小
  • YGC 年輕代垃圾回收次數
  • YGCT 年輕代垃圾回收消耗時間
  • FGC 老年代垃圾回收次數
  • FGCT 老年代垃圾回收消耗時間
  • GCT 垃圾回收消耗總時間

-gcutil和-gc參數類似,只不過輸出字段不是實際值,而是百分比。

 

字段解釋:

  • S0 survivor0使用百分比
  • S1 survivor1使用百分比
  • E Eden區使用百分比
  • O 老年代使用百分比
  • M 元數據區使用百分比
  • CCS 壓縮使用百分比
  • YGC 年輕代垃圾回收次數
  • YGCT 年輕代垃圾回收消耗時間
  • FGC 老年代垃圾回收次數
  • FGCT 老年代垃圾回收消耗時間
  • GCT 垃圾回收消耗總時間

3、jinfo:Java配置信息工具

jinfo的作用是實時的查看和調整虛擬機 各項參數。使用jps命令的-v參數可以查看虛擬機啓動時顯式指定的參數列表。如果想知道未被顯式指定的參數系統默認值,那就需要查找相關資料或者使用jinfo命令配合相關參數進行查看。

 命令格式:

jinfo [option] <pid>

options:參數解釋

  • -flag <name> 打印指定名稱的參數
  • -flag [+|-]<name> 打開或關閉參數
  • -flag <name>=<value> 設置參數
  • -flags 打印所有參數
  • -sysprops 打印系統配置
  • <no option> 打印上面兩個選項

常用示例展示:

1)、查看JVM參數和系統配置

jinfo 11666

jinfo  -flags 11666

jinfo   -sysprops 11666

2)、查看打印GC日誌參數

jinfo -flag PrintGC 11666

jinfo -flag PrintGCDetails 11666

3)、關閉GC參數

jinfo -flag -PrintGC 11666

jinfo -flag -PrintGCDetails 11666

還可以使用下面的命令查看哪些參數可以使用jinfo命令來管理:

java -XX:+PrintFlagsFinal -version | grep manageable

4、jmap:java內存映像工具

 jmap是用來生成對dump文件和查看堆相關的各類信息命令,例如查看finalize執行隊列,heap的詳細信息和 使用情況。

命令格式:

jmap [option] <pid> (連接正在執行的進程)
jmap [option] <executable <core> (連接一個core文件)
jmap [option] [server_id@]<remote server IP or hostname> (鏈接遠程服務器)

option參數解釋:

  • <none> to print same info as Solaris pmap
  • -heap 打印java heap摘要
  • -histo[:live] 打印堆中的java對象統計信息
  • -clstats 打印類加載器統計信息
  • -finalizerinfo 打印在f-queue中等待執行finalizer方法的對象
  • -dump:<dump-options> 生成java堆的dump文件

      dump-options:

      live 只轉儲存活的對象,如果沒有指定則轉儲所有對象

      format=b 二進制格式

      file=<file> 轉儲文件到 <file>

  • -F 強制選項

常用示例:

1)、jmap -dump:live,format=b,file=dump.hprof 11666

輸出:

Dumping heap to /dump.hprof ...

Heap dump file created

這個命令是要把java堆中的存活對象信息轉儲到dump.hprof文件

2)、jmap -finalizerinfo 11666

輸出:

Attaching to process ID 11666, please wait...

Debugger attached successfully.

Server compiler detected.

JVM version is 24.71-b01

Number of objects pending for finalization: 0

輸出結果的含義爲當前沒有在等待執行finalizer方法的對象

3)、jmap -heap 11666

輸出堆的詳細信息

Attaching to process ID 11666, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.25-b02

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration: //堆內存初始化配置
   MinHeapFreeRatio         = 0 //對應jvm啓動參數-XX:MinHeapFreeRatio設置JVM堆最小空閒比率(default 40)
   MaxHeapFreeRatio         = 100 //對應jvm啓動參數 -XX:MaxHeapFreeRatio設置JVM堆最大空閒比率(default 70)
   MaxHeapSize              = 1073741824 (1024.0MB) //對應jvm啓動參數-XX:MaxHeapSize=設置JVM堆的最大大小
   NewSize                  = 22020096 (21.0MB) //對應jvm啓動參數-XX:NewSize=設置JVM堆的新生代的默認大小
   MaxNewSize               = 357564416 (341.0MB) //對應jvm啓動參數-XX:MaxNewSize=設置JVM堆的新生代的最大大小
   OldSize                  = 45088768 (43.0MB) //對應jvm啓動參數-XX:OldSize=<value>:設置JVM堆的老年代的大小
   NewRatio                 = 2 //對應jvm啓動參數-XX:NewRatio=:新生代和老生代的大小比率
   SurvivorRatio            = 8 //對應jvm啓動參數-XX:SurvivorRatio=設置新生代中Eden區與Survivor區的大小比值
   MetaspaceSize            = 21807104 (20.796875MB) // 元數據區大小
   CompressedClassSpaceSize = 1073741824 (1024.0MB) //類壓縮空間大小
   MaxMetaspaceSize         = 17592186044415 MB //元數據區最大大小
   G1HeapRegionSize         = 0 (0.0MB) //G1垃圾收集器每個Region大小

Heap Usage: //堆內存使用情況
PS Young Generation 
Eden Space: //Eden區內存分佈
   capacity = 17825792 (17.0MB) //Eden區總容量
   used     = 12704088 (12.115562438964844MB) //Eden區已使用
   free     = 5121704 (4.884437561035156MB) //Eden區剩餘容量
   71.26801434685203% used //Eden區使用比率
From Space: //其中一個Survivor區的內存分佈
   capacity = 2097152 (2.0MB)
   used     = 1703936 (1.625MB)
   free     = 393216 (0.375MB)
   81.25% used
To Space: //另一個Survivor區的內存分佈
   capacity = 2097152 (2.0MB)
   used     = 0 (0.0MB)
   free     = 2097152 (2.0MB)
   0.0% used
PS Old Generation
   capacity = 52428800 (50.0MB) //老年代容量
   used     = 28325712 (27.013504028320312MB) //老年代已使用
   free     = 24103088 (22.986495971679688MB) //老年代空閒
   54.027008056640625% used //老年代使用比率
interned Strings occupying 2075304 bytes.

4)、jmap -histo:live 11666 | more

輸出存活對象統計信息

輸出:

num     #instances         #bytes  class name
----------------------------------------------
1:         46608        1111232  java.lang.String
2:          6919         734516  java.lang.Class
3:          4787         536164  java.net.SocksSocketImpl
4:         15935         497100  java.util.concurrent.ConcurrentHashMap$Node
5:         28561         436016  java.lang.Object

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

jhat命令和jmap搭配使用,來分析jmap生成的堆轉儲快照。jhat內置了一個小型的HTTP/HTML服務器,生成dump分析結果後,可以在瀏覽器中進行查看。不過在實際環境中,很少有人會使用該命令就行快照分析,除非手頭上別無選擇。主要原因:一是一般不會在部署應用程序的服務器上直接分析 dump文件,即使可以這樣做,也會盡量將dump文件複製到別的機器上完成分析,因爲分析工作是一個耗時而且消耗硬件資源的過程。另一個原因就是jhat的分析功能相對來說比較簡陋。

命令格式:

jhat [option] [dumpfile]

option參數解釋:

  • -stack false: 關閉對象分配調用堆棧的跟蹤
  • -refs false: 關閉對象引用的跟蹤
  • -port <port>: HTTP服務器端口,默認是7000
  • -debug <int>: debug級別

   0: 無debug輸出

   1: Debug hprof file parsing

   2: Debug hprof file parsing, no server

  • -version 分析報告版本

6、jstack:java堆棧跟蹤工具

jstack是用來查看JVM線程快照的命令,線程快照是當前JVM線程正在執行的方法堆棧 集合。使用jstack命令可以定位線程出現長時間卡頓的原因,例如死鎖, 死循環等。jstack還可以查看 程序崩潰是生成的core文件中的stack信息。

命令格式:

jstack [option] vmid

option參數:

  • -F: 當正常輸出的請求不被響應是,強制輸出線程 堆棧
  • -l:除堆棧外,顯示關於鎖的附加信息
  • -m:如果調用本地方法的話,可以顯示C/C++的堆棧

常用示例:

jstack -l 11666 | more

Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.25-b02 mixed mode):

"Attach Listener" #25525 daemon prio=9 os_prio=0 tid=0x00007fd374002000 nid=0x70e8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
    - None
......

在JDK1.5中,java.lang.Thread類新增了一個getAllStackTraces()方法用於獲取虛擬機中所有線程的StackTraceElement對象。使用這個方法可以通過簡單的幾行代碼完成jstack的大部分功能。

 

7、JDK的可視化工具

主要常用的有jconsole jvisualvm 相關的具體用法, 各位讀者在具體的使用過程中 慢慢摸索就可以了。在這裏就不過多的描述。

 

jvisualvm:

 

發佈了364 篇原創文章 · 獲贊 389 · 訪問量 141萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章