獲取Java線程轉(zhuǎn)儲(chǔ)的常用方法(推薦)
1. 線程轉(zhuǎn)儲(chǔ)簡(jiǎn)介
線程轉(zhuǎn)儲(chǔ)(Thread Dump)就是JVM中所有線程狀態(tài)信息的一次快照。
線程轉(zhuǎn)儲(chǔ)一般使用文本格式, 可以將其保存到文本文件中, 然后人工查看和分析, 或者使用工具/API自動(dòng)分析。
Java中的線程模型, 直接使用了操作系統(tǒng)的線程調(diào)度模型, 只進(jìn)行簡(jiǎn)單的封裝。
線程調(diào)用棧, 也稱(chēng)為方法調(diào)用棧。 比如在程序執(zhí)行過(guò)程中, 有一連串的方法調(diào)用鏈:obj1.method2
調(diào)用了obj2.methodB
,obj2.methodB
又調(diào)用了obj3.methodC
。 每個(gè)線程的狀態(tài)都可以通過(guò)這種調(diào)用棧來(lái)表示。
線程轉(zhuǎn)儲(chǔ)展示了各個(gè)線程的行為, 對(duì)于診斷和排查問(wèn)題非常有用。
下面我們通過(guò)具體示例, 來(lái)演示各種獲取Java線程轉(zhuǎn)儲(chǔ)的工具, 以及使用方法。
2. 使用JDK自帶的工具
我們一般使用JDK自帶的命令行工具來(lái)獲取Java應(yīng)用程序的線程轉(zhuǎn)儲(chǔ)。 這些工具都在JDK主目錄的bin文件夾下。
所以, 只要配置好 PATH 路徑即可。 如果不會(huì)配置, 可以參考:JDK環(huán)境準(zhǔn)備
2.1 jstack 工具
jstack 是JDK內(nèi)置的一款命令行工具, 專(zhuān)門(mén)用來(lái)查看線程狀態(tài), 也可以用來(lái)執(zhí)行線程轉(zhuǎn)儲(chǔ)。
一般先通過(guò)jps
或者ps
命令找到Java進(jìn)程對(duì)應(yīng)的pid, 然后在控制臺(tái)中通過(guò)pid來(lái)輸出線程轉(zhuǎn)儲(chǔ)。 當(dāng)然, 我們也可以將輸出內(nèi)容重定向到某個(gè)文件中。
使用jstack工具獲取線程轉(zhuǎn)儲(chǔ)的基本參數(shù)格式為:
jstack [-F] [-l] [-m] <pid>
下面請(qǐng)看具體的演示:
# 1. 查看幫助信息 jstack -help
輸出的內(nèi)容類(lèi)似于:
Usage: jstack [-l] <pid> (to connect to running process) jstack -F [-m] [-l] <pid> (to connect to a hung process) jstack [-m] [-l] <executable> <core> (to connect to a core file) jstack [-m] [-l] [server_id@]<remote server IP or hostname> (to connect to a remote debug server) Options: -F to force a thread dump. Use when jstack <pid> does not respond (process is hung) -m to print both java and native frames (mixed mode) -l long listing. Prints additional information about locks -h or -help to print this help message
對(duì)應(yīng)的參數(shù)選項(xiàng)是可選的。 具體含義如下:
-F
選項(xiàng), 強(qiáng)制執(zhí)行線程轉(zhuǎn)儲(chǔ); 有時(shí)候jstack pid
會(huì)假死, 則可以加上-F
標(biāo)志-l
選項(xiàng), 會(huì)查找堆內(nèi)存中擁有的同步器以及資源鎖-m
選項(xiàng), 額外打印 native棧幀(C和C++的)
例如, 獲取線程轉(zhuǎn)儲(chǔ)并將結(jié)果輸出到文件:
jstack -F 17264 > /tmp/threaddump.txt
使用jps
命令可以獲取本地Java進(jìn)程的 pid。
2.2 Java Mission Control
Java Mission Control(JMC)是一款客戶(hù)端圖形界面工具, 用于收集和分析Java應(yīng)用程序的各種數(shù)據(jù)。
啟動(dòng)JMC后, 首先會(huì)顯示本地計(jì)算機(jī)上運(yùn)行的Java進(jìn)程列表。 當(dāng)然也可以通過(guò)JMC連接到遠(yuǎn)程Java進(jìn)程。
可以鼠標(biāo)右鍵單擊對(duì)應(yīng)的進(jìn)程, 選擇 “Start Flight Recording(開(kāi)始飛行記錄)” 。 結(jié)束之后, “Threads(線程)” 選項(xiàng)卡會(huì)顯示“線程轉(zhuǎn)儲(chǔ)”:
2.3 jvisualvm
jvisualvm 是一款客戶(hù)端圖形界面工具, 既簡(jiǎn)單又實(shí)用, 可用來(lái)監(jiān)控 Java應(yīng)用程序, 對(duì)JVM進(jìn)行故障排查和性能分析。
也可以用來(lái)獲取線程轉(zhuǎn)儲(chǔ)。 鼠標(biāo)右鍵單擊Java進(jìn)程, 選擇“ Thread Dump”選項(xiàng), 則可以創(chuàng)建線程轉(zhuǎn)儲(chǔ), 完成后會(huì)在新選項(xiàng)卡中自動(dòng)打開(kāi):
2.4 jcmd
jcmd工具本質(zhì)上是向目標(biāo)JVM發(fā)送一串命令。 盡管支持很多功能, 但不支持連接遠(yuǎn)程JVM - 只能在Java進(jìn)程的本地機(jī)器上使用。
其中一個(gè)命令是Thread.print
, 用來(lái)獲取線程轉(zhuǎn)儲(chǔ), 示例用法如下:
jcmd 17264 Thread.print
2.5 jconsole
jconsole 工具也可以查看線程棧跟蹤。
打開(kāi)jconsole并連接到正在運(yùn)行的Java進(jìn)程, 導(dǎo)航到“線程”選項(xiàng)卡, 可以查看每個(gè)線程的堆棧跟蹤:
2.6 小結(jié)
事實(shí)證明, 可以使用JDK中的很多工具來(lái)獲取線程轉(zhuǎn)儲(chǔ)。 讓我們回顧一下, 并總結(jié)它們的優(yōu)缺點(diǎn):
jstack jmc jvisualvm jcmd jconsole
3. 使用Linux命令
在企業(yè)應(yīng)用服務(wù)器中, 出于安全原因, 可能只安裝了 JRE。 這時(shí)候沒(méi)法使用這些JDK內(nèi)置的工具。
但還是有辦法獲取線程轉(zhuǎn)儲(chǔ)。
3.1 使用kill -3
指令
在Unix/Linux之類(lèi)的系統(tǒng)中, 可以使用kill
命令獲取線程轉(zhuǎn)儲(chǔ), 底層實(shí)現(xiàn)原理, 則是通過(guò)系統(tǒng)調(diào)用kill()
將信號(hào)參數(shù)發(fā)送給進(jìn)程。 這里需要發(fā)送的是-3
信號(hào)。
一般先通過(guò)jps
找到JAVA進(jìn)程對(duì)應(yīng)的pid,kill -3
使用示例如下:
kill -3 17264
3.2Ctrl + Break
(Windows)
在Windows操作系統(tǒng)的命令行窗口中, 可使用組合鍵Ctrl + Break
來(lái)獲取線程轉(zhuǎn)儲(chǔ)。 當(dāng)然, 需要先導(dǎo)航至啟動(dòng)Java程序的控制臺(tái)窗口, 然后同時(shí)按下CTRL
鍵和Break
鍵。
需要注意的是, 某些鍵盤(pán)是沒(méi)有 “Break
” 鍵的。
在這種情況下, 可以組合使用CTRL
,SHIFT
, 以及Pause
鍵。
這兩個(gè)命令都可以將線程轉(zhuǎn)儲(chǔ)打印到控制臺(tái)。
4. 通過(guò)編程方式使用ThreadMxBean
JMX技術(shù)支持各種各樣的花式操作。 可通過(guò)ThreadMxBean
來(lái)執(zhí)行線程轉(zhuǎn)儲(chǔ)。
示例代碼如下:
private static String threadDump(boolean lockedMonitors, boolean lockedSynchronizers) { StringBuffer threadDump = new StringBuffer(System.lineSeparator()); ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); for(ThreadInfo threadInfo : threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) { threadDump.append(threadInfo.toString()); } return threadDump.toString(); }
上面代碼做的事情很簡(jiǎn)單, 先通過(guò)ManagementFactory
獲取ThreadMxBean
對(duì)象。
方法的布爾參數(shù)lockedMonitors
和lockedSynchronizers
, 表示是否導(dǎo)出持有的同步器和管程鎖。
5. 總結(jié)
我們通過(guò)具體示例展示了獲取線程轉(zhuǎn)儲(chǔ)的各種方法。
首先介紹的是各種JDK內(nèi)置工具,
然后討論了命令行方式,
最后介紹了JMX編程的方式。
完整的示例代碼請(qǐng)參考GitHub倉(cāng)庫(kù)。
到此這篇關(guān)于獲取Java線程轉(zhuǎn)儲(chǔ)的常用方法的文章就介紹到這了,更多相關(guān)Java線程轉(zhuǎn)儲(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java集成開(kāi)發(fā)SpringBoot生成接口文檔示例實(shí)現(xiàn)
這篇文章主要為大家介紹了java集成開(kāi)發(fā)SpringBoot如何生成接口文檔的示例實(shí)現(xiàn)過(guò)程,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10SpringBoot集成MyBatisPlus+MySQL的實(shí)現(xiàn)
MybatisPlus是國(guó)產(chǎn)的第三方插件, 它封裝了許多常用的CURDapi,免去了我們寫(xiě)mapper.xml的重復(fù)勞動(dòng),本文主要介紹了SpringBoot集成MyBatisPlus+MySQL的實(shí)現(xiàn),感興趣的可以了解一下2023-10-10java多線程編程之使用thread類(lèi)創(chuàng)建線程
在Java中創(chuàng)建線程有兩種方法:使用Thread類(lèi)和使用Runnable接口。在使用Runnable接口時(shí)需要建立一個(gè)Thread實(shí)例2014-01-01Java加權(quán)負(fù)載均衡策略實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了Java加權(quán)負(fù)載均衡策略實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03JAVA隨機(jī)數(shù)隨機(jī)字母的實(shí)現(xiàn)(微信搶紅包小練習(xí))
這篇文章主要介紹了JAVA隨機(jī)數(shù)隨機(jī)字母的實(shí)現(xiàn)(微信搶紅包小練習(xí)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04