效能監控之常見JDK命令列工具整理

語言: CN / TW / HK

「這是我參與11月更文挑戰的第20天,活動詳情檢視:2021最後一次更文挑戰


一、概述

我們在做效能分析的時候,知識、經驗是關鍵基礎,資料是依據,工具是運用知識處理資料的手段。這裡說的資料包括:執行引數、執行日誌、異常堆疊、GC日誌、執行緒快照(threaddump/javacore 檔案)、堆轉儲快照(heapdump/hprof 檔案)等。

本文只討論JDK8的常用引數及工具。

二、JVM 引數型別

引數型別大概可以分為三類:

  • 標準引數
  • X引數
  • XX引數

1、標準引數

JVM各個版本基本上不變的引數

舉栗子:

  • -help
  • -server
  • -client
  • -version
  • -showversion
  • -cp
  • -classpath

標準引數

2、-X 引數

一般用的不多,不同版本的JVM可能有變化

舉栗子: -Xint:完全解釋執行,不會轉換成原生代碼

xinit

-Xcomp:第一次使用就編譯成原生代碼,第一次比較慢

xcomp

-Xmixed:混合模式,JVM自己來決定是否編譯成原生代碼

xmixed

3、-XXX 引數

非標準化引數,相對不太穩定,主要用於JVM調優和Debug,主要分為Boolean與非Boolean兩種型別

3.1、Boolean 型別

格式:-XX:[+-]表示啟用或者禁用name屬性 比如:

  • -XX:+UseConcMarkSweepGC啟用CMS垃圾回收器
  • -XX:+UseG1GC 啟用G1垃圾回收器

垃圾回收器

3.2、非 Boolean 型別

格式:-XX:=表示name的屬性的值是value 比如:

  • -XX:MaxGCPauseMilis=500(GC最大停頓時間為500毫秒)
  • XX:GCTimeRatio=19
  • -Xmx -Xms
    • -Xms等價於-XX:InitialHeapSize(初始化堆大小)
    • --Xms等價於-XX:MaxHeapSize(最大堆大小)

三、執行時 JVM 引數檢視(最關鍵)

  • -XX:+PrintFlagsInitial(初始值)
  • -XX:+PrintFlagsFinal(最終值)

這裡寫圖片描述

列表內容 - =表示預設值 - :=被使用者或JVM修改後的值

儲存成文字下載下來大概有700多個引數

列印引數

這裡寫圖片描述

  • -XX:+UnlockExperimentaIVMOptions(解鎖實驗引數才能賦值)
  • -XX:+UnlockDiagnosticVMoptions(解鎖診斷引數)
  • -XX:+PrintCommandLineFlags(列印命令列引數)

1、jps(JVM Process Status Tool)

虛擬機器程序狀態工具,即可檢視執行態的Java程序,使用頻度最高的JDK命令列工具之一,因為其他工具大多需要輸入它查詢到LVMID(Local Virtual machine Identifier)來確定監控哪一個程序

jps命令格式:

$jps [ options ] [ hostid ]$

jps工具主要選項: | 選項 | 作用| | ------------- |:-------------| | -q | 只輸出LVMID,省略類名 | | -m | 輸出JVM Main函式的引數 | |-l | 輸出類名,如果是JAR,輸出其路徑| |-v| 輸出JVM啟動引數|

舉栗子: 檢視執行java程序PID

這裡寫圖片描述

jps -l 檢視完全類名

jsp -l

官方參考連結:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html

2、jinfo(Configuration Info for Java)

JVM配置資訊工具,可實時檢視和調整JVM的各項引數

命令格式:

$jinfo [ option ] pid$

檢視執行中java程序的引數

  • jinfo -flag name pid:當前設定的引數
  • jin -flags name pid:賦值的引數

舉栗子: 檢視最大記憶體

檢視最大記憶體

檢視垃圾回收器,是否啟用

檢視垃圾回收器

3、jstat(JVM Statistics Monitoring Tool)

監控JVM各種執行狀態資訊的命令列工具,可以監控JVM中的類載入、記憶體、GC、JIT編譯等執行資料

命令格式: $jstat [ generalOption | outputOptions vmid [ interval[s|ms] [ count ] ]$

舉栗子:

  • -class 類載入器
  • -compiler JIT
  • -gc GC狀態
  • -printcomplilation HotSpot編譯統計
  • -gccapacity 各區大小
  • -gccause 最後一次GC統計和原因
  • -gcnew 年輕代狀態
  • -gcnewcapacity 年輕代大小
  • -gcold 年老代大小
  • -gcoldcapacity 年老代大小
  • -gcutil GC彙總統計

檢視類裝載,解除安裝數量,總空間以及類裝載耗費的時間

類載入

官方參考連結:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

4、垃圾回收(效能監控非常有用)

實時動態檢視記憶體變化

gc

  • S0CS1CS0US1US0S1的總量與使用量 -ECEUEden區總量與使用量
  • OCOUOld區總量與使用量
  • MCMUMetaspace區總量與使用量
  • CCSCCCSU:壓縮類空間總量與使用量
  • YGCYGCTYoungGC的次數與時間
  • FGCFGCTFullGC的次數與時間
  • GCT:總的GC時間

5、JIT 編譯

  • -complier:輸出JIT編譯器編譯過的方法、耗時等資訊
  • -printcomplilation:輸出已經被JIT編譯的方法

6、jmap(Memory Map for Java)

JAVA記憶體映像工具,一方面用於生成堆轉儲存快照(heapdump或dump檔案),另一方面可以查詢finalize執行佇列、Java堆和永久代的詳細資訊,如空間使用率、當前使用的垃圾收集器等

jmap命令格式: $jmap [ options ] pid$ $jmap [ options ] executable core$ $jmap [ options ] [ pid ] [email protected] ] remote-hostname-or-IP$

jmap工具主要選項 | 選項 | 作用| | ------------- |:-------------| | -dump | 生成JAVA堆轉儲快照| |-finalize| 顯示在F-Queue中等待finalizer執行緒執行finalize方法的物件| |-heap |顯示堆詳細資訊,如使用的垃圾回收器、引數配置、分代狀況等| |-histo |顯示堆中物件的統計資訊,包括類、例項數量、合計容量等| |-permstat |以ClassLoader為統計口徑顯示永久代的記憶體狀態| |-F| 強制生成dump快照|

使用jmap生成dump檔案

dump

jmap列印記憶體直方圖或heap資訊

記憶體直方圖

官方參考連結:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html

7、jstack(Stack Track for Java)

JAVA堆疊跟蹤工具,用於生成JVM當前時刻的執行緒快照(threaddump或javacore檔案)。執行緒快照即當前JVM每一條執行緒正在執行的方法堆疊集合

主要用途:定位執行緒長時間停頓的原因,如:執行緒死鎖、死迴圈、請求外部資源導致的長時間等待等。

jstack命令格式: $jstack [ options ] pid$ $jstack [ options ] executable core$ $jstack [ options ] [ [email protected] ] remote-hostname-or-IP$

jstack工具主要選項: | 選項 | 作用| | ------------- |:-------------| |-F |強制輸出執行緒堆疊| |-l| 除堆疊外,顯示關於鎖的附加資訊| |-m |如果呼叫本地方法的話,可以顯示C++的資訊|

使用jstack生成執行緒堆疊,jstack -l 23554 > test.threaddump儲存到檔案

jstack生成執行緒堆疊

官方參考連結:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstack.html

舉個小栗子: Java程式抓最耗CPU的執行緒,可以通過這麼幾步:

  1. 通過top命令(top之後再按shift+H可以顯示執行緒)檢視CPU使用率高的執行緒;
  2. 將這個執行緒號轉換為16進位制,如:printf %x
  3. 使用jps檢視伺服器的Java程序號;
  4. 使用jstack [程序號]列印當前的程序堆疊;
  5. 從列印的資訊中,找到第2步得到的執行緒號,看看這個執行緒在做什麼。 不一定一次就能抓準執行緒狀態,可以第1步時多記幾個執行緒。

四、JVM 記憶體結構

JVM記憶體結構

  • 堆區:S0和S1大小相同,同一個時間點上只有一個啟用,另一個是空的
  • 非堆區:作業系統的本地記憶體,獨立於JVM的堆區之外的
  • Metaspace:JDK8新特性
  • CCS:啟用短指標才會有
  • CodeCache:把JAVA程式碼轉換為Native程式碼存在此處,如果沒有開啟JIT編譯,此處記憶體不存在
  • CCS:啟用短指標的時候存到此處