jdk在安裝的時候會提供一些性能分析、故障診斷、JVM監控之類的工具,了解這些工具對我們分析JVM記憶體、JVM調優有一定的幫助,本篇文章來學習一下。
監控類工具
jps
jps(JVM Process Status)是檢視正在運作的虛拟機程序的工具。jps能擷取程序id,是以會被經常使用。在 linux 中,一般自帶了 OpenJdk,一般情況下 JPS 等指令不能用,要麼選擇去安裝 JPS 等插件,要麼把 OpenJdk 解除安裝,重新安裝 Oracle 的 JDK。
文法:
jps [ options ] [ hostid ]
- options可選項,有以下選擇:
參數 | 含義 |
-q | 隻顯示程序 |
-m | 輸出主函數傳入的參數 |
-l | 輸出應用程式主類完整 package 名稱或 jar 完整名稱. |
-v | 列出 jvm 參數 |
-V | 隻生成本地JVM辨別符清單 |
-J | 向JVM傳遞參數。例如:-J-Xms48m,設定JVM初始記憶體為48m |
- hostid :遠端位址,可選項,指定特定主機的IP或者域名,也可以指定具體協定端口,不指定則檢視目前機器的相關資訊,hostid所指機器必須開啟jstatd服務。
測試:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SN0cjN5MmMkZDO4U2YyczMzYzXwQjM1EDMxAzLcBTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
57312 JvmToolsApplication
這個是我運作的一個用于測試的springboot項目。
jstat
jstat(JVM Statistics Monitoring Tool )是用于監視虛拟機各種運作狀态資訊的指令行工具。它可以顯示本地或者遠端虛拟機程序中的類裝載、記憶體、垃圾收集、JIT 編譯等運作資料,在沒有 GUI 圖形界面,隻提供了純文字控制台環境的伺服器上,它将是運作期定位虛拟機性能問題的首選工具。
文法:
jstat [ generalOption | outputOptions vmid [ interval[s|ms] [ count ] ]
- generalOption :正常選項,必填項。有兩個參數可選
-
:幫助資訊-help
-
:對應着下面的outputOptions-options
- outputOptions:輸出選項,必填項。有以下選項
參數 | 含義 |
-class | 顯示類加載器行為資訊 |
-compiler | 顯示有關JVM實時編譯器行為的統計資訊 |
-gc | 顯示有關GC堆行為的統計資訊。 |
-gccapacity | 顯示各分區大小 |
-gccause | 顯示最近一次 GC 統計資訊和原因 |
-gcnew | 顯示新生代行為的統計資訊。 |
-gcnewcapacity | 顯示新生代記憶體大小 |
-gcold | 顯示老年代統計資訊 |
-gcoldcapacity | 顯示老年代記憶體大小 |
-gcmetacapacity | 顯示元空間記憶體大小 |
-gcutil | 顯示GC統計彙總資訊 |
-printcompilation | 顯示HotSpot 編譯統計資訊 |
outputOptions參數後面還能加以下可選參數:
- -h n:每n個樣本(輸出行)顯示一個列标題,預設值為0,顯示列标題的第一行資料。
- -t:第一列顯示為時間戳
- -J:向應用程式傳遞啟動參數
- vmid :虛拟機辨別
- interval:指定時間采樣間隔時間,機關秒(s)或者毫秒(ms),預設機關是毫秒
- count :采樣次數,指定時間内采樣多少次。
測試:
- 統計gc資訊
-
jvm 自帶調優工具一覽 - 57312 是測試項目JvmToolsApplication在虛拟機中的程序id。
-
這個指令是在100ms内擷取10次gc統計資訊jstat -gc 57312 100 10
-
jvm 自帶調優工具一覽 - 結果中的列分别代表以下意思:
- S0C:第一個幸存區(From 區)的大小
- S1C:第二個幸存區(To 區)的大小
- S0U:第一個幸存區的使用大小
- S1U:第二個幸存區的使用大小
- EC:伊甸園(Eden)區的大小
- EU:伊甸園(Eden)區的使用大小
- OC:老年代大小
- OU:老年代使用大小
- MC:方法區大小
- MU:方法區使用大小
- CCSC:壓縮類空間大小
- CCSU:壓縮類空間使用大小
- YGC:年輕代垃圾回收次數
- YGCT:年輕代垃圾回收消耗時間
- FGC:老年代垃圾回收次數
- FGCT:老年代垃圾回收消耗時間
- GCT:垃圾回收消耗總時間
故障診斷類工具
jinfo
jinfo(Configuration Info for Java) 可以實時地檢視和調整虛拟機的各項參數。jinfo不僅能擷取到虛拟機指令行參數,還能擷取到系統參數。
文法:
-
:檢視和調整本地程序虛拟機參數jinfo [ option ] pid
option:
- -flag name:name為jvm參數名
- -flag [+|-]name:開啟或者關閉一個Boolean的jvm參數
- -flag name=value:設定jvm參數值
- -flags:查詢虛拟機參數
- -sysprops:可以檢視由 System.getProperties()取得的參數
測試:
-
flag測試
可以通過
指令擷取虛拟機參數,這是一個很長的清單,其中紅框部分如果是manageable則表示可以在運作時修改。java -XX:+PrintFlagsFinal –version
-
jvm 自帶調優工具一覽 - 我們就随便找一個參數UseTLAB進行查詢,可以看到它是否開啟
-
jvm 自帶調優工具一覽 -
擷取虛拟機參數
先修改一下項目啟動參數,加上
:-XX:+PrintGC -XX:SurvivorRatio=6
- 重新開機項目,并通過jps擷取到程序id
-
jvm 自帶調優工具一覽 - 再通過
指令擷取項目啟動參數jinfo -flags 67776
-
jvm 自帶調優工具一覽 - 還可以擷取上面配置的某一個參數
jinfo -flag SurvivorRatio 67776
-
jvm 自帶調優工具一覽
通過 jinfo 指令,我們可以在生産上臨時打開一下 GC日志或者進行一些資料的配置(不需要重新開機應用條件下),也是我們去排查問題的一個關鍵指令。
jmap
jmap(Memory Map for Java) 列印給定程序或遠端調試伺服器的共享對象記憶體映射或堆記憶體詳細資訊。jmap也可用于生成堆轉儲快照(一般稱為 heapdump 或 dump 檔案),除此之外它還可以查詢 finalize 執行隊列、Java 堆和永 久代的詳細資訊,如空間使用率、目前用的是哪種收集器等。和 jinfo 指令一樣,jmap 有不少功能在 Windows 平台下都是受限的,除了生成 dump 檔案的 -dump 選項和用于檢視每個類的執行個體、空間占用統計的-histo 選項在所有作業系統都提供之外,其餘選項都隻能在 Linux/Solaris 下使用。
文法:
jmap [ options ] pid
options 有如下選項:
- -heap:列印 heap 的概要資訊
-
jvm 自帶調優工具一覽
Heap Configuration: ##堆配置情況,也就是 JVM 參數配置的結果[平常說的 tomcat 配置 JVM 參數,就是在配置這些]
MinHeapFreeRatio = 0 //最小堆使用比例
MaxHeapFreeRatio = 100 //最大堆可用比例
MaxHeapSize = 4261412864 (4064.0MB) //最大堆空間大小
NewSize = 88604672 (84.5MB) ) //新生代配置設定大小
MaxNewSize = 1420296192 (1354.5MB) //最大可新生代配置設定大小
OldSize = 177733632 (169.5MB) //老年代大小
NewRatio = 2 //新生代比例
SurvivorRatio = 6 //新生代與 suvivor 的比例
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 = 66584576 (63.5MB) //Eden容量
used = 27941200 (26.646804809570312MB) //Eden區已使用大小
free = 38643376 (36.85319519042969MB) //未使用
41.96347214105561% used //使用比例
From Space: //survior1 區
capacity = 11010048 (10.5MB)
used = 8497840 (8.104171752929688MB)
free = 2512208 (2.3958282470703125MB)
77.18258812313988% used
To Space: //survior2 區
capacity = 11010048 (10.5MB)
used = 0 (0.0MB)
free = 11010048 (10.5MB)
0.0% used
PS Old Generation //老年代使用情況
capacity = 115867648 (110.5MB)
used = 10553152 (10.06427001953125MB)
free = 105314496 (100.43572998046875MB)
9.10793666925905%
-
-histo 列印每個 class 的執行個體數目,記憶體占用,類全名資訊.
文法:
,live參數表示統計活躍狀态的對象jmap –histo:live <pid>
-
jvm 自帶調優工具一覽 - -histo 列印的執行個體數目太多了,看不過來,顯示那麼多也沒什麼用,是以在Linux系統上可以使用
指令隻展示前10行,具體行數可以自己定義。jmap –histo <pid> | head -10
- -finalizerinfo :列印正等候回收的對象的資訊
- –clstats:列印堆中類加載器資訊,它會列印類加載器的名字、活躍度、位址、父加載器、加載了多少個類等。
- -dump:[live,] format=b, file=filename:生成的堆轉儲快照
-
jvm 自帶調優工具一覽 - 通過-dump指令可以在指定檔案夾生成dump檔案,之後再搭配jhat來分析dump檔案,dump檔案的字尾也可以是
或者hprof
,dump檔案本身是一個二進制檔案。bin
- -h或-help:列印幫助資訊
- -J:傳遞虛拟機參數
jhat
jhat (Heap Dump Browser)可以讓一個dump檔案以web服務的的形式通路。
上面我們用jmap工具生成了一個dump檔案,現在可以通過jhat 工具,讓它再浏覽器端通路到。
Server is ready表示啟動成功,端口号為7000,然後在浏覽器端通路http://localhost:7000/,可以看到dump檔案内容
文法:
jhat [ options ] heap-dump-file
- -stack false|true:關閉對象配置設定調用棧跟蹤。 如果配置設定位置資訊在堆轉儲中不可用. 則必須将此标志設定為 false. 預設值為 true.
- -refs false|true:關閉對象引用跟蹤。 預設值為 true. 預設情況下, 傳回的指針是指向其他特定對象的對象,如反向連結或輸入引用, 會統計/計算堆中的所有對象。
- -port port-number:http端口号指定,就是上面通過浏覽器通路的端口号,預設是7000
- -exclude exclude-file:指定一個檔案,該檔案列出應從可達對象查詢中排除的資料成員。
- -baseline exclude-file:指定基線堆轉儲。兩個堆轉儲中具有相同對象ID的對象被标記為不是新的。其他對象被标記為新的。這對于比較兩個不同的堆轉儲非常有用。
- -debug int:設定debug等級,0意味着不輸出debug資訊,等級越高輸出的日志越詳細。
- -version:版本号
jhat指令在JDK9、JDK10中已經被删除了,官方建議使用VisualVM代替。
jstack
jstack(Stack Trace for Java)指令用于生成虛拟機目前時刻的線程快照。線程快照就是目前虛拟機内每一條線程正在執行的方法堆棧的集合,生成線程快照的主 要目的是定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導緻的長時間等待等都是導緻線程長時間停頓的常見原因。
文法:
jstack [ options ] pid
options 選項:
- -m:列印同時具有Java和本機C/C++幀的混合模式堆跟蹤。
- -l:列印有關鎖的其他資訊,例如擁有java.util.concurrent同步器的清單
可視化工具
對于桌面作業系統,java提供了jconsole和jvisualvm可視化工具。可視化工具就是将上面幾個指令行工具整合到一起使用的一個工具。
jconsole
jconsole指令啟動一個圖形控制台工具,該工具允許您監視和管理本地或遠端計算機上的Java應用程式和虛拟機。
指令行輸入
Jconsole
指令
選擇要監控的程式,可選擇本地程序也可以選擇遠端程序,如果選擇遠端程序的話要在伺服器開啟JMX,一般不開啟。
進入控制台首頁
- 概覽:可以看到堆記憶體的使用量、線程、類加載的變化、CPU占用率
- 記憶體:可以看到各個分區的使用量變化,也可以執行GC操作
-
jvm 自帶調優工具一覽 - 線程:可以看到線程數變化情況,也可以檢視具體線程詳細資訊,檢測是否有死鎖
-
jvm 自帶調優工具一覽 - 類:類加載數量變化的折線圖,可根據時間範圍進行篩選
-
jvm 自帶調優工具一覽 - VM概要:檢視JVM各種資訊的彙總
-
jvm 自帶調優工具一覽 - MBean:檢視Mbean資訊、屬性資訊、方法資訊等。通過getProperty可以擷取系統屬性,比如在輸入框輸入
,就會彈出對應的屬性值。sun.desktop
-
jvm 自帶調優工具一覽 - JConsole啟動的時候還可以附加其他參數:
- -interval=n:更新間隔頻率,機關秒(s),預設4秒更新一次
- -notile:對于2個及以上連接配接不平鋪視窗
- -pluginpath plugins:啟動的同時指定一個插件
jvisualvm
jvisualvm是一個監控運作時java應用程式的圖形界面工具。jvisualvm大緻和Jconsole差不多,就是多了抽樣器和profiler,感興趣的可以自己試一下。
指令行輸入
jvisualvm
就可以啟動jvisualvm可視化界面了。
選擇要檢視的應用程式就可以進入監控界面
jhat指令是用來加載jmap生成的dump檔案的,前面不是說官方建議使用VisualVM代替jhat指令嘛,那就是說jvisualvm也可以加載dump檔案。
選擇堆dump
打開就能看到之前生成的dump檔案裡面的内容了
jvisualvm還可以安裝插件
這裡選擇安裝Visual GC
安裝好之後就可以看到jvm記憶體變化情況,通過Visual GC可以很好地了解JVM運作時區域資訊。