欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JVM 命令行工具的使用

 更新時(shí)間:2024年04月11日 10:04:59   作者:布道師小羊  
造成Java應(yīng)用出現(xiàn)性能問題的因素非常多,想要定位這些問題,一款優(yōu)秀的性能診斷工具必不可少,本文主要介紹了JVM 命令行工具的使用,具有一定的參考價(jià)值,感興趣的可以了解一下

性能問題是軟件工程師在日常工作中需要經(jīng)常面對(duì)和解決的問題,在用戶體驗(yàn)至上的今天,解決好應(yīng)用的性能問題能帶來非常大的收益。工欲善其事,必先利其器,想要解決性能相關(guān)問題,必須要有比較好的性能診斷工具。Java作為最流行的編程語(yǔ)言之一,應(yīng)用的性能診斷一直受到業(yè)界廣泛關(guān)注。造成Java應(yīng)用出現(xiàn)性能問題的因素非常多,例如線程控制、磁盤讀寫、數(shù)據(jù)庫(kù)訪問、網(wǎng)絡(luò)I/O、垃圾收集等。想要定位這些問題,一款優(yōu)秀的性能診斷工具必不可少,就好比中醫(yī)、西醫(yī)看病,中醫(yī)講究的是望、聞、問、切,西醫(yī)則是借助各種檢查儀器。

1、概述

JDK本身已經(jīng)集成了很多診斷工具。在大家剛接觸Java學(xué)習(xí)的時(shí)候,最先了解的兩個(gè)命令就是javac和java,但是除此之外,還有一些其他工具可以使用,可是并非所有的程序員都了解其他命令行程序的作用,接下來我們一起看看其他命令行程序的作用。進(jìn)入到安裝JDK的bin目錄,會(huì)發(fā)現(xiàn)還有一系列輔助工具。這些輔助工具用來獲取目標(biāo)JVM不同方面、不同層次的信息,幫助開發(fā)人員很好地解決Java應(yīng)用程序的一些疑難雜癥。Mac系統(tǒng)bin目錄的內(nèi)容如下圖所示:

在這里插入圖片描述

Windows系統(tǒng)bin目錄的內(nèi)容如下圖所示:

在這里插入圖片描述

雖然在Windows系統(tǒng)下都是exe格式的可執(zhí)行文件。但事實(shí)上,它們只是Java程序的一層包裝,其真正實(shí)現(xiàn)是在tools.jar中,如下圖所示。以jps工具為例,在控制臺(tái)執(zhí)行jps命令和執(zhí)行java -classpath %Java_HOME%/lib/tools.jar sun.tools.jps.Jps命令是等價(jià)的,即jps.exe只是這個(gè)命令的一層包裝。下面介紹一些常用的命令工具。

在這里插入圖片描述

2、jps:查看正在運(yùn)行的Java進(jìn)程

jps(JVM Process Status Tool)命令用于查看系統(tǒng)內(nèi)所有的JVM進(jìn)程,可根據(jù)參數(shù)選項(xiàng)指定是否顯示JVM的執(zhí)行主類[包含main()方法的類],以及進(jìn)程的本地JVMID(Local Virtual Machine Identifier),對(duì)于本地JVM進(jìn)程來說,進(jìn)程的本地JVMID與操作系統(tǒng)的進(jìn)程ID是一致的。簡(jiǎn)單來說,就是Java提供的一個(gè)顯示當(dāng)前所有Java進(jìn)程pid的命令,和Linux系統(tǒng)里的ps命令很相似,ps命令主要是用來顯示當(dāng)前系統(tǒng)的進(jìn)程情況,比如查看進(jìn)程列表和進(jìn)程ID。在日常工作中,此命令也是最常用的命令之一。

jps的基本使用語(yǔ)法如下:

jps  [ options ] [ hostid ]

1、jps命令[options]選項(xiàng)說明:

在這里插入圖片描述

2、[hostid]說明:

hostid表示目標(biāo)主機(jī)的主機(jī)名或IP地址,如果省略該參數(shù),則目標(biāo)主機(jī)為本地主機(jī)。如果想要遠(yuǎn)程監(jiān)控主機(jī)上的Java程序,需要安裝jstatd。對(duì)于網(wǎng)絡(luò)安全要求非常嚴(yán)格的場(chǎng)所,需要自定義策略文件來滿足對(duì)特定的主機(jī)或網(wǎng)絡(luò)的訪問,但是這種技術(shù)容易受到IP地址欺詐攻擊。如果由于安全問題無法通過定制的策略文件處理,那么最安全的操作是在主機(jī)本地使用jstat和jps工具。

3、使用案例:

Linux上啟動(dòng)Tomcat(一種Web應(yīng)用服務(wù)器),然后在Linux上面使用ps命令查看Tomcat進(jìn)程ID使用,如下所示:

     ps -ef | grep"tomcat"

運(yùn)行結(jié)果如下圖所示:

在這里插入圖片描述

可以看到進(jìn)程ID是1224。使用jps -l命令查看,如下圖上所示:

在這里插入圖片描述

3、jstat:查看JVM統(tǒng)計(jì)信息

jstat(JVM Statistics Monitoring Tool)用于收集JVM各方面的運(yùn)行數(shù)據(jù),顯示本地或遠(yuǎn)程JVM進(jìn)程中的類裝載、內(nèi)存、垃圾收集、JIT編譯等運(yùn)行數(shù)據(jù)。在沒有圖形用戶界面時(shí),只提供了純文本控制臺(tái)環(huán)境的服務(wù)器上,它是運(yùn)行期定位JVM性能問題的首選工具。常用于檢測(cè)垃圾回收問題以及內(nèi)存泄漏問題。它的功能非常強(qiáng)大,可以通過它查看堆信息的詳細(xì)情況。

jstat的基本使用語(yǔ)法如下:

     jstat -<option>[-t] [-h<lines>] <vmid>[<interval>[<count>]]

使用下面的命令可以查看jstat相關(guān)參數(shù):

     jstat -h 或 jstat -help

1、[options]選項(xiàng)說明

在這里插入圖片描述

2、[-t]參數(shù)說明

[-t]參數(shù)可以在輸出信息前加上一個(gè)Timestamp列,顯示程序的運(yùn)行時(shí)間??梢员容^Java進(jìn)程的啟動(dòng)時(shí)間以及總GC時(shí)間(GCT列),或者兩次測(cè)量的間隔時(shí)間以及總GC時(shí)間的增量,來得出GC時(shí)間占運(yùn)行時(shí)間的比例。如果該比例超過20%,則說明目前堆的壓力較大;如果該比例超過90%,則說明堆里幾乎沒有可用空間,隨時(shí)都可能拋出OOM異常。

3、[-h]參數(shù)說明

[-h]參數(shù)可以在周期性數(shù)據(jù)輸岀時(shí),輸出設(shè)定的行數(shù)的數(shù)據(jù)后輸出一個(gè)表頭信息。

4、[interval]參數(shù)說明

[interval]參數(shù)用于指定輸出統(tǒng)計(jì)數(shù)據(jù)的周期,單位為毫秒,簡(jiǎn)單來說就是查詢間隔時(shí)間。

5、[count]參數(shù)說明

[count]用于指定查詢的總次數(shù)。

6、使用案列

由于jstat參數(shù)選項(xiàng)比較多,這里只列舉一個(gè)啟動(dòng)了Tomcat的Linux服務(wù)器案例,查看其監(jiān)視狀態(tài),命令如下所示。

在這里插入圖片描述

運(yùn)行結(jié)果如下圖所示:

在這里插入圖片描述

運(yùn)行結(jié)果的各列表示的含義如下表所示:

在這里插入圖片描述

jstat還可以用來判斷是否出現(xiàn)內(nèi)存泄漏,步驟如下:

  • (1)在長(zhǎng)時(shí)間運(yùn)行的Java程序中,可以運(yùn)行jstat命令連續(xù)獲取多行性能數(shù)據(jù),并取這幾行數(shù)據(jù)中OU列(即已占用的老年代內(nèi)存)的最小值。
  • (2)每隔一段較長(zhǎng)的時(shí)間重復(fù)一次上述操作,獲得多組OU最小值。如果這些值呈上漲趨勢(shì),則說明該Java程序的老年代內(nèi)存已使用量在不斷上漲,這意味著無法回收的對(duì)象在不斷增加,因此很有可能存在內(nèi)存泄漏。

4、jinfo:實(shí)時(shí)查看和修改JVM配置參數(shù)

jinfo(Configuration Info for Java)可用于查看和調(diào)整JVM的配置參數(shù)。在很多情況下,Java應(yīng)用程序不會(huì)指定所有的JVM參數(shù)。而此時(shí),開發(fā)人員可能不知道某一個(gè)具體的JVM參數(shù)的默認(rèn)值。在這種情況下,可能需要通過查找文檔獲取某個(gè)參數(shù)的默認(rèn)值。這個(gè)查找過程可能是非常艱難的。但有了jinfo工具,開發(fā)人員可以很方便地找到JVM參數(shù)的當(dāng)前值。上面講解的jps -v命令雖然可以查看JVM啟動(dòng)時(shí)顯示指定的參數(shù)列表,但是如果想要知道未被顯示指定的參數(shù)的系統(tǒng)默認(rèn)值,就需要用到j(luò)info工具了。

第二個(gè)作用就是在程序運(yùn)行時(shí)修改部分參數(shù),并使之立即生效。并非所有參數(shù)都支持動(dòng)態(tài)修改,只有被標(biāo)記為manageable的參數(shù)可以被實(shí)時(shí)修改。其實(shí),這個(gè)修改能力是極其有限的,使用下面的命令查看被標(biāo)記為manageable的參數(shù)。

     java -XX:+PrintFlagsFinal -version | grep manageable

運(yùn)行結(jié)果如下圖所示:

在這里插入圖片描述

jinfo的基本使用語(yǔ)法如下:

     jinfo  [ options ] pid

1、[ options ]選項(xiàng)說明

jinfo工具options主要選項(xiàng)如下表所示:

在這里插入圖片描述

2、pid說明

Java進(jìn)程ID,必須要加上。

3、使用案例

由于jinfo可以查看JVM配置信息,也可用于調(diào)整JVM的配置參數(shù),下面分兩類案例分別講解如何使用。

4、jinfo用于查看JVM配置信息案例

在這里插入圖片描述

程序很簡(jiǎn)單,只需要保證程序在執(zhí)行狀態(tài)即可。首先使用jps命令查看進(jìn)程ID,如下所示:

     #查看進(jìn)程ID
     jps -l

執(zhí)行結(jié)果如下:

C:\Users\Administrator>jps -l
15008 com.yang.ScannerTest
14820 sun.tools.jps.Jps

上面出現(xiàn)兩個(gè)結(jié)果,ScannerTest程序的進(jìn)程ID是15008,另外一個(gè)進(jìn)程ID表示jps命令本身的進(jìn)程。下面使用jinfo命令來查看JVM配置參數(shù),命令如下:
(1)根據(jù)進(jìn)程ID查詢?nèi)繀?shù)和系統(tǒng)屬性:

     #查看全部參數(shù)和系統(tǒng)屬性,
     jinfo  15008

因篇幅所限,只展示部分結(jié)果,如下所示:

在這里插入圖片描述

結(jié)果中含有Java系統(tǒng)屬性(System Properties)和JVM參數(shù)(VM Flags)。

(2)根據(jù)進(jìn)程ID查詢系統(tǒng)屬性(選項(xiàng):-sysprops)命令如下:

     #查看系統(tǒng)屬性
     jinfo -sysprops 15008

運(yùn)行結(jié)果如下,篇幅原因只展示部分結(jié)果,如下所示:

在這里插入圖片描述

通過Java代碼獲取系統(tǒng)屬性如下代碼清單所示:

在這里插入圖片描述

運(yùn)行結(jié)果如下圖所示:

在這里插入圖片描述

通過比較兩者結(jié)果一致。

(3)查看全部JVM參數(shù)配置(選項(xiàng):flags),命令如下:

     #查看全部JVM參數(shù)配置
     jinfo -flags 15008

運(yùn)行結(jié)果如下圖所示:

在這里插入圖片描述

可以看到里面包含初始堆大小、最大堆大小等參數(shù)配置。

(4)查看某個(gè)Java進(jìn)程的具體參數(shù)的值(選項(xiàng):-flag name),命令如下:

     #查看JVM是否使用了ParallelGC垃圾收集器
     jinfo –flag UseParallelGC 15008

運(yùn)行結(jié)果如下圖所示:

在這里插入圖片描述

可以看到結(jié)果為-XX:+UseParallelGC,其中UseParallelGC前面的“+”表示已經(jīng)使用,如果沒有使用的話,用“-”表示。也可以查看某個(gè)參數(shù)的具體數(shù)值,比如查看新生代對(duì)象晉升到老年代對(duì)象的最大年齡,命令如下:

     #新生代對(duì)象晉升到老年代對(duì)象的最大年齡
     jinfo -flag MaxTenuringThreshold 15008

在這里插入圖片描述

從結(jié)果可知新生代對(duì)象晉升到老年代對(duì)象的最大年齡是15。

5、jinfo用于修改JVM配置信息案例

(1)開啟或者關(guān)閉對(duì)應(yīng)名稱的參數(shù)(-flag [±]name)(或者稱為修改布爾類型的參數(shù))。

首先查看是否開啟輸出GC日志的參數(shù),如果GC日志參數(shù)是開啟狀態(tài),那么使用jinfo命令關(guān)閉;如果GC日志參數(shù)是關(guān)閉狀態(tài),那么使用jinfo命令開啟,命令如下:

在這里插入圖片描述

對(duì)于布爾類型的JVM參數(shù),不僅可以使用-flag [±]name的形式來進(jìn)行值的改變,也可以使用-flag name=value的形式修改運(yùn)行時(shí)的JVM參數(shù)。但是對(duì)value賦值必須是1或者0,1表示“+”,0表示“-”,如下所示:

在這里插入圖片描述

(2)修改對(duì)應(yīng)名稱的參數(shù)(-flag name=value)(或者稱為修改非布爾類型的參數(shù))。

修改非布爾類型MaxHeapFreeRatio的值,命令如下:

在這里插入圖片描述

運(yùn)行結(jié)果如下圖所示:

在這里插入圖片描述

除了使用jinfo查看JVM配置參數(shù)之外,還有如下方式:

在這里插入圖片描述

java -XX:+PrintFlagsInitial執(zhí)行結(jié)果如下,展示部分結(jié)果:

在這里插入圖片描述

java -XX:+PrintFlagsFinal執(zhí)行結(jié)果如下,展示部分結(jié)果:

在這里插入圖片描述

輸出結(jié)果中包含五列。第一列表示參數(shù)的數(shù)據(jù)類型,第二列表示參數(shù)名稱,第四列表示參數(shù)的值,第五列表示參數(shù)的類別。第三列“=”是參數(shù)的默認(rèn)值,而“:=”表示參數(shù)被用戶或者JVM賦值了??梢酝ㄟ^“java -XX:+PrintFlagsFinal |grep":="”命令查看哪些參數(shù)是被用戶或者JVM賦值的。java -XX:+PrintFlagsInitial只展示了第三列為“=”的參數(shù)。

java -XX:+PrintCommandLineFlags執(zhí)行結(jié)果如下,該參數(shù)輸出被用戶或者JVM設(shè)置過的詳細(xì)的-XX參數(shù)的名稱和值:

     -XX:InitialHeapSize=268435456
     -XX:MaxHeapSize=4294967296
     -XX:+PrintCommandLineFlags
     -XX:+UseCompressedClassPointers
     -XX:+UseCompressedOops
     -XX:+UseParallelGC

該參數(shù)的結(jié)果是java -XX:+PrintFlagsFinal的結(jié)果中帶有“:=”的部分參數(shù)。可以通過該命令快捷地查看修改過的參數(shù)。

5、jmap:導(dǎo)出內(nèi)存映像文件和內(nèi)存使用情況

jmap(JVM Memory Map)用于生成JVM的內(nèi)存轉(zhuǎn)儲(chǔ)快照,生成heapdump文件且可以查詢finalize執(zhí)行隊(duì)列,以及Java堆與元空間的一些信息。jmap的作用并不僅僅是為了獲取dump文件(堆轉(zhuǎn)儲(chǔ)快照文件,二進(jìn)制文件),它還可以獲取目標(biāo)Java進(jìn)程的內(nèi)存相關(guān)信息,包括Java堆各區(qū)域的使用情況、堆中對(duì)象的統(tǒng)計(jì)信息、類加載信息等。

開發(fā)人員可以在控制臺(tái)中輸入命令“jmap-help”,查閱jmap工具的具體使用方式和標(biāo)準(zhǔn)選項(xiàng)配置。jmap的基本使用語(yǔ)法如下:

在這里插入圖片描述

1、[ options ]選項(xiàng)說明

jmap工具[options]主要選項(xiàng)如下表所示:

在這里插入圖片描述

這些參數(shù)和Linux下輸入顯示的命令多少會(huì)有一些不同,也受JDK版本的影響。其中選項(xiàng)-dump、-heap、-histo是開發(fā)人員在工作中使用頻率較高的指令。

2、使用案例

(1)-dump選項(xiàng):導(dǎo)出內(nèi)存映像文件。

一般來說,使用jmap指令生成dump文件的操作算得上是最常用的jmap命令之一,將堆中所有存活對(duì)象導(dǎo)出至一個(gè)文件之中。執(zhí)行該命令,JVM會(huì)將整個(gè)Java堆二進(jìn)制格式轉(zhuǎn)儲(chǔ)到指定filename的文件中。live子選項(xiàng)是可選的,如果指定了live子選項(xiàng),堆中只有存活的對(duì)象會(huì)被轉(zhuǎn)儲(chǔ)。

通常在寫dump文件前會(huì)觸發(fā)一次Full GC,所以dump文件里保存的都是Full GC后留下的對(duì)象信息。由于生成dump文件比較耗時(shí),因此大家需要耐心等待,尤其是大內(nèi)存鏡像生成dump文件需要耗費(fèi)更長(zhǎng)的時(shí)間來完成。

如果想要瀏覽dump文件,大家可以使用jhat(Java堆分析工具)讀取生成的文件,也可以使用可視化工具進(jìn)行解讀,比如MAT內(nèi)存分析工具。獲取dump文件有手動(dòng)獲取和自動(dòng)獲取兩種方式。

手動(dòng)獲取的意思是當(dāng)發(fā)現(xiàn)系統(tǒng)需要優(yōu)化或者需要解決內(nèi)存問題時(shí),需要開發(fā)者主動(dòng)執(zhí)行jmap命令,導(dǎo)出dump文件,手動(dòng)獲取命令如下:

     #手動(dòng)獲取堆內(nèi)存全部信息
     jmap -dump:format=b,file=<filename.hprof><pid>
     #手動(dòng)獲取堆內(nèi)存存活對(duì)象全部信息
     jmap -dump:live,format=b,file=<filename.hprof><pid>

代碼清單如下所示,往堆內(nèi)存中存放數(shù)據(jù),然后導(dǎo)出dump文件。

在這里插入圖片描述

運(yùn)行程序,最終該程序會(huì)產(chǎn)生內(nèi)存溢出,在執(zhí)行過程中使用上述命令導(dǎo)出dump文件即可,運(yùn)行結(jié)果如下圖所示:

在這里插入圖片描述

上述命令中,file表示指定文件目錄,這里將文件放到D盤根目錄,10692表示Java進(jìn)程ID,結(jié)果如下圖所示,dump1.hprof就是導(dǎo)出的結(jié)果文件。

在這里插入圖片描述

當(dāng)程序發(fā)生內(nèi)存溢出退出系統(tǒng)時(shí),一些瞬時(shí)信息都隨著程序的終止而消失,而重現(xiàn)OOM問題往往比較困難或者耗時(shí)。若能在OOM時(shí),自動(dòng)導(dǎo)出dump文件就顯得非常迫切。可以配置JVM參數(shù)“-XX:+HeapDumpOnOutOfMemoryError:”使程序發(fā)生OOM時(shí),導(dǎo)出應(yīng)用程序的當(dāng)前堆快照。

依然使用上面代碼,在啟動(dòng)程序之前,在idea中添加如下JVM參數(shù)配置:

     -Xms60m
     -Xmx60m
     -XX:+HeapDumpOnOutOfMemoryError
     -XX:HeapDumpPath=d:/autoDump.hprof

添加參數(shù)如下圖所示:

在這里插入圖片描述

啟動(dòng)程序,運(yùn)行結(jié)果如下圖所示:

在這里插入圖片描述

從結(jié)果可知,程序發(fā)生了內(nèi)存溢出,此時(shí)dump文件自動(dòng)生成到目標(biāo)目錄中,如下圖所示:

在這里插入圖片描述

(2)-heap選項(xiàng):顯示堆內(nèi)存相關(guān)信息

命令如下:

     #1520表示當(dāng)前進(jìn)程ID
     jmap -heap 1520

運(yùn)行結(jié)果如下:

在這里插入圖片描述

打印heap的概要信息、GC使用的算法、heap的配置和使用情況,可以判斷當(dāng)前堆內(nèi)存使用情況以及垃圾回收情況。

可以看到最大堆大小為60MB,和前面的VM配置信息一致;新生代大小等于Eden區(qū)加From區(qū)加To的大小,總共為20MB,符合新生代和老年代比例大小為2:1;老年代大小為40MB,老年代使用率達(dá)到了99.53%,說明老年代空間是不足的。

(3)-hiso選項(xiàng):顯示堆中對(duì)象的統(tǒng)計(jì)信息:

     #1520表示當(dāng)前進(jìn)程ID
     jmap -histo 1520

運(yùn)行結(jié)果如下,由于篇幅原因,展示部分結(jié)果:

在這里插入圖片描述

上面結(jié)果中,instances表示當(dāng)前的實(shí)例數(shù)量;bytes表示對(duì)象占用的內(nèi)存大??;classs name表示類名,按照內(nèi)存大小逆序排列。

(4)-permstat選項(xiàng):

該選項(xiàng)主要以ClassLoader為口徑輸出永久代的內(nèi)存狀態(tài)信息,僅對(duì)Linux和solaris平臺(tái)有效。

(5)-finalizerinfo選項(xiàng)。

該選項(xiàng)主要用來顯示F-Queue中等待Finalize線程執(zhí)行finalize方法的對(duì)象,就是說查看堆積在finalizer隊(duì)列中的對(duì)象。僅對(duì)Linux和solaris平臺(tái)有效。

(6)-F選項(xiàng)

該選項(xiàng)用于當(dāng)JVM進(jìn)程對(duì)-dump選項(xiàng)沒有任何響應(yīng)時(shí),可使用此選項(xiàng)強(qiáng)制執(zhí)行生成dump文件。僅對(duì)Linux和solaris平臺(tái)有效。

由于jmap將訪問堆中的所有對(duì)象,為了保證在此過程中不被應(yīng)用線程干擾,jmap需要借助安全點(diǎn)機(jī)制,讓所有線程不改變堆中數(shù)據(jù)的狀態(tài)。也就是說,由jmap導(dǎo)出的堆快照必定是安全點(diǎn)位置的。這可能導(dǎo)致基于該快照的分析結(jié)果存在偏差。例如,假設(shè)在編譯生成的機(jī)器碼中,某些對(duì)象的生命周期在兩個(gè)安全點(diǎn)之間,那么:live選項(xiàng)將無法探知到這些對(duì)象。另外如果某個(gè)線程長(zhǎng)時(shí)間無法跑到安全點(diǎn),jmap將一直等待下去。與前面講的jstat不同,垃圾收集器會(huì)主動(dòng)將jstat所需要的摘要數(shù)據(jù)保存至固定位置中,而jstat只需要直接讀取即可。

6、jhat:JDK自帶堆分析工具

jhat(JVM Heap Analysis Tool)命令一般與jmap命令搭配使用,用于分析jmap生成的dump文件(堆轉(zhuǎn)儲(chǔ)快照)。jhat內(nèi)置了一個(gè)微型的HTTP/HTML服務(wù)器,生成dump文件的分析結(jié)果后,用戶可以在瀏覽器中查看分析結(jié)果。

使用了jhat命令,就啟動(dòng)了一個(gè)http服務(wù),端口是7000,即通過訪問http://localhost:7000/就可以在瀏覽器中查看結(jié)果。jhat命令在JDK9中已經(jīng)被刪除,官方建議用VisualVM代替。實(shí)際工作中一般不會(huì)直接在生產(chǎn)服務(wù)器使用jhat分析dump文件。

7、jstack:打印JVM中線程快照

jstack(JVM Stack Trace)用于生成JVM指定進(jìn)程當(dāng)前時(shí)刻的線程快照(Thread Dump),方便用戶跟蹤JVM堆棧信息。線程快照就是當(dāng)前JVM內(nèi)指定進(jìn)程的每一條線程正在執(zhí)行的方法堆棧的集合。

生成線程快照的作用是可用于定位線程出現(xiàn)長(zhǎng)時(shí)間停頓的原因,如線程間死鎖、死循環(huán)、請(qǐng)求外部資源導(dǎo)致的長(zhǎng)時(shí)間等待等問題,這些都是導(dǎo)致線程長(zhǎng)時(shí)間停頓的常見原因。當(dāng)線程出現(xiàn)停頓時(shí),就可以用jstack顯示各個(gè)線程調(diào)用的堆棧情況。

在線程快照中,有下面幾種狀態(tài),如下表所示:

在這里插入圖片描述

其中線程的Deadlock、Waiting on condition、Waiting on monitor entry以及Blocked狀態(tài)需要在分析線程棧的時(shí)候重點(diǎn)關(guān)注。

jstack的基本使用語(yǔ)法如下:

     jstack [ option ] <pid>

1、[ options ]選項(xiàng)說明

jstack工具[options]主要選項(xiàng)如下表所示:

在這里插入圖片描述

2、使用案例

代碼清單如下演示了線程死鎖,使用jstack命令觀察線程狀態(tài)。

在這里插入圖片描述

上面例子很簡(jiǎn)單,啟動(dòng)了兩個(gè)線程,分別獲取對(duì)方的資源,如此造成死鎖。下面啟動(dòng)程序,使用jstack命令查看線程狀態(tài),命令如下,其中1776是程序的進(jìn)程ID。

     jstack 1776

運(yùn)行結(jié)果如下:

在這里插入圖片描述

從上面結(jié)果中可以發(fā)現(xiàn),Thread-1線程和Thread-0線程互相等待對(duì)方的資源,問題代碼出現(xiàn)“com.yang.ThreadDeadLock$2.run()”行。在死鎖情況出現(xiàn)時(shí),可以很方便地幫助定位到問題。也可以通過Thread.getAllStackTraces()方法獲取所有線程的狀態(tài),代碼清單如下所示:

在這里插入圖片描述

運(yùn)行結(jié)果如下圖所示,可以看到各個(gè)線程的狀態(tài):

在這里插入圖片描述

8、jcmd:多功能命令行

在JDK1.7以后,新增了一個(gè)命令行工具jcmd。它是一個(gè)多功能的工具,可以用來實(shí)現(xiàn)前面除了jstat之外所有命令的功能,比如用它來導(dǎo)出堆、內(nèi)存使用、查看Java進(jìn)程、導(dǎo)出線程信息、執(zhí)行GC、JVM運(yùn)行時(shí)間等。jcmd擁有jmap的大部分功能,并且官方也推薦使用jcmd命令代替jmap命令。

至于jstat的功能,雖然jcmd復(fù)制了jstat的部分代碼,并支持通過PerfCounter.print子命令來打印所有的Performance Counter,但是它沒有保留jstat的輸出格式,也沒有重復(fù)打印的功能。

jcmd的基本使用語(yǔ)法如下表所示:

在這里插入圖片描述

9、jstatd:遠(yuǎn)程主機(jī)信息收集

之前的指令只涉及監(jiān)控本機(jī)的Java應(yīng)用程序,而在這些工具中,一些監(jiān)控工具也支持對(duì)遠(yuǎn)程計(jì)算機(jī)的監(jiān)控(如jps、jstat)。為了啟用遠(yuǎn)程監(jiān)控,則需要配合使用jstatd工具。

命令jstatd是一個(gè)RMI服務(wù)端程序,它的作用相當(dāng)于代理服務(wù)器,建立本地計(jì)算機(jī)與遠(yuǎn)程監(jiān)控工具的通信。jstatd服務(wù)器將本機(jī)的Java應(yīng)用程序信息傳遞到遠(yuǎn)程計(jì)算機(jī)。執(zhí)行原理如下圖所示:

在這里插入圖片描述

直接打開jstatd服務(wù)器可能會(huì)拋出訪問拒絕異常,這是因?yàn)閖statd程序沒有足夠的權(quán)限,如下圖所示:

在這里插入圖片描述

10、小結(jié)

介紹了JDK自帶的命令行工具及其常用參數(shù)。當(dāng)Java應(yīng)用和服務(wù)出現(xiàn)莫名的卡頓、CPU飆升等問題時(shí),通過JDK自帶的狀態(tài)監(jiān)控命令和圖形化工具,可以非常方便地分析對(duì)應(yīng)進(jìn)程的JVM狀態(tài),進(jìn)而定位問題并解決問題。

到此這篇關(guān)于JVM 命令行工具的使用的文章就介紹到這了,更多相關(guān)JVM 命令行工具內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論