Java虛擬機器詳解(七)------虛擬機器監控和分析工具(1)——命令列
通過前面的幾篇部落格,我們介紹了Java虛擬機器的記憶體分配以及記憶體回收等理論知識,瞭解這些知識對於我們在實際生產環境中提高系統的執行效率是有很大的幫助的。但是話又說回來,在實際生產環境中,線上專案正在執行,我們怎麼去監控虛擬機器執行效率?又或者線上專案發生了OOM,異常堆疊資訊,我們又怎麼去抓取,然後怎麼去分析定位問題呢?
本篇部落格,我們就來介紹各種虛擬機器監控和分析工具,當然都是命令列工具,不夠直觀,下篇部落格我們會介紹各種視覺化工具。
1、jps:顯示虛擬機器程序
JVM Process Status Tools ,顯示指定系統內所有的 HotSpot 虛擬機器程序。
該命令有如下常用引數:
①、-l
顯示應用程式main類的完整包名稱或應用程式的JAR檔案的完整路徑名。
②、-v
顯示虛擬機器啟動時的JVM引數。
③、-m
顯示虛擬機器程序啟動時傳遞給主類 main() 函式的引數。
比如,我在伺服器上啟動了一個Tomcat,如下:
然後,輸入 jps 命令,列印資訊如下:
這裡的 Bootstrap 便是啟動的 Tomcat程序。可以加上 -v 引數,顯示所有傳遞給 JVM的引數資訊。
PS:jps 命令預設是沒有安裝的,需要進行安裝,具體安裝步驟可以百度,我這裡就不做詳細介紹了。
jps更多詳細資訊,請參考官方文件:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html
2、jstat:統計監視虛擬機器資訊工具
JVM Statistics Monitoring Tool,用於收集虛擬機器各方面的執行資料。
jstat 是用於監視虛擬機器各種執行時狀態資訊的命令列工具。它可以顯示本地或遠端虛擬機器程序中的類裝載、記憶體、垃圾收集、JIT編譯等執行時資料,它是執行時期定位虛擬機器效能問題的首選工具。但是終究只是命令列工具,後面我們會介紹圖形化工具,更加直觀。
該命令監控本地的格式如下:
jstat -引數 vmid 取樣間隔時間 取樣次數
①、常用引數有如下
②、vmid
表示目標虛擬機器的識別符號,在Linux系統上可以通過上小節我們介紹的 jps 命令,前面輸出的數字便是程序 PID。在windows平臺上,可以通過工作管理員檢視。
③、取樣間隔時間
預設單位是毫毛,必須是正整數。
例項1:這裡我們加入 -class 引數,檢視類裝載資訊:
相關表頭資訊:
Loaded:載入的類數量。
Bytes:載入的類位元組KB大小。
Unloaded:解除安裝的類數量。
Bytes:解除安裝的類位元組KB大小。
Time:執行類載入和解除安裝操作所花費的時間。
jstat更多詳細資訊,請參考官方文件:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html
3、jinfo:實時的檢視和調整虛擬機器各項引數
jinfo(Confiiguration Info for Java):實時的檢視和調整虛擬機器各項引數
jinfo ,通過此命令,我們可以實時的檢視和調整虛擬機器的各項引數(包括顯示指定或預設配置的)。
該命令格式如下:
jinfo [ 選項 ] pid
①、常用選項如下
一、沒有選項
列印系統屬性名稱鍵值對。
二、-引數名稱
列印指定引數的名稱和值。
三、-flag [+|-] 引數名稱
啟用或者禁用指定的布林命令。
四、-flag name=value
設定引數name的值為value
五、-sysprops
列印Java屬性名稱鍵值對。
②、pid
程序號,和上面一樣,可以通過jps命令獲取。
jinfo更多詳細資訊,請參考官方文件:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jinfo.html
4、jmap:記憶體映像工具
jmap(Memory Map for Java):用於生成堆儲存快照
jmap主要用於獲取堆儲存快照檔案,在生產環境中,發生OOM(堆記憶體溢位)異常時,我們可以通過這個快照檔案來快速定位到具體程式碼位置。
這個命令還可以查詢 finalize 佇列,Java堆和永久代資訊,如空間使用率、當前用的是哪種垃圾收集器等。
該命令格式如下:
jmap [引數] pid
①、常用引數如下:
對於堆記憶體溢位異常,在前面介紹虛擬機器引數時,我們介紹過,通過下面兩個引數,也能夠列印堆記憶體快照。
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath
下面,我們通過如下程式碼,演示堆記憶體溢位異常:
1 package com.ys.algorithmproject.leetcode.demo.JVM; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /** 7 * Create by YSOcean 8 * 9 */ 10 public class JmapTest { 11 private static final int _1MB = 1024*1024; 12 13 /** 14 * 虛擬機器引數設定: -Xms20M -Xmx20M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./ 15 * @param args 16 */ 17 public static void main(String[] args) { 18 List<Object> list = new ArrayList<>(); 19 while(true){ 20 list.add(new Object[_1MB]); 21 } 22 } 23 }
設定虛擬機器引數後,然後執行這段程式碼,就會發生堆記憶體溢位異常,並在根目錄下生成快照檔案 java_pid10840.hprof。
那麼,怎麼通過 jmap 命令來生成堆記憶體快照呢?
jmap -dump:format=b,file=heap20190821.hprof 16823
後面的數字是程序PID,可以通過jps命令來獲取。
得到堆記憶體快照了,那麼我們怎麼去檢視呢?
在eclipse中,可以下載 MAT 工具,而在 IDEA中,可以下載 JProfiler 外掛。實在不行,可以用我們下篇部落格介紹的幾個視覺化工具,具體情況見下篇部落格。
jmap更多詳細資訊,請參考官方文件:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html
5、jstack:Java堆疊跟蹤工具
Stack Trace for Java,用於生成虛擬機器當前時刻的執行緒快照。
執行緒快照其實就是當前虛擬機器每一條執行緒正在執行的堆疊的集合,通過執行緒快照可以用來定位執行緒出現長時間停頓的原因(執行緒間死鎖、死迴圈、請求外部資源導致的長時間等待)。
該命令格式如下:
jstack [選項] pid
①、常用選項如下:
參考文件:https://docs.oracle.com/javase/8/docs/technotes/tools/index.