Thread dumps
(線程轉儲)能幫助咱們判斷 CPU 峯值、死鎖、內存異常、應用反應遲鈍、響應時間變長和其餘系統問題。一些在線的分析工具好比 http://fastthread.io/ 也能幫助咱們分析和定位問題,可是這些工具都要求有一個 dump 文件。所以在這篇文章當中,我總結了7中抓取 Java Thread Dumps 文件的方式。java
jstack
是一個抓取 thread dump
文件的有效的命令行工具,它位於 JDK 目錄裏的 bin 文件夾下(JDK_HOME\bin),如下是抓取 dump 文件的命令:tomcat
jstack -l <pid> > <file-path>
說明:安全
pid: Java 應用的進程 id ,也就是須要抓取 dump 文件的應用進程 id。app
file-path: 保存 dump 文件的路徑。工具
示例:性能
jstack -l 37320 > /opt/tmp/threadDump.txt
上面的例子演示了用 jstack 生成 dump 文件到 /opt/tmp/threadDump.txt
目錄下。ui
從 Java5 開始,jstack 被包含進了 jdk 當中,若是你使用老版本的 jdk,要考慮使用其餘方式。this
處於安全方面的考慮,有一部分生產環境的機器只包含 JRE 環境,所以就不能使用 jstack 工具了,在這種狀況下,咱們可使用 kill -3
的方式:spa
kill -3 <pid>
說明:操作系統
示例:
kill -3 37320
當使用 kill -3
生成 dump 文件時,dump 文件會被輸出到標準錯誤流。假如你的應用運行在 tomcat 上,dump 內容將被髮送到<TOMCAT_HOME>/logs/catalina.out
文件裏。
Java VisualVM 是一個能夠提供 JVM 信息的圖形界面工具。它位於 JDK_HOME\bin\jvisualvm.exe
文件裏。從 JDK6 Update7 開始,它被包含進 JDK 裏。
運行 jvisualvm,在左側面板中(以下圖所示),列出了運行的 JVM 信息,這個工具能夠從本地或者遠程運行的 JVM 裏抓取 dump 文件。
點擊上圖的進程名稱對應的 Thread Dump
按鈕,將會生成 dump 文件,以下圖所示:
Java Mission Control (JMC) 是一個能從本地或生產環境中收集和分析數據的工具,從 Oracle JDK 7 Update 40 開始,它被包含進 JDK 裏,它能夠從 JVM 裏生成 dump 文件。JMC 位於 JDK_HOME\bin\jmc.exe
文件裏:
運行該工具以後,你能夠看到運行在本地的 Java 進程,它也能夠鏈接到遠程機器。雙擊你想要生成 dump 文件的 Java 進程,點擊Flight Recorder
,你會看到如下的對話框:
在 Thread Dump
下拉框,你能夠選擇生成 dump 文件的時間間隔。在上面的例子裏,每隔60秒將會生成一個 dump 文件。選擇完成以後啓動 Flight recorder ,能夠在 Threads 面板看到 dump 文件的內容:
這種方式僅僅在 Windows 操做系統上有效:
在控制檯窗口上選中命令行
在命令行窗口上按 「Ctrl + Break」 命令
而後會生成 dump 文件,dump 文件的內容會被打印在命令行窗口上。
注意1: 有幾款筆記本(好比 Lenovo T 系列)已經取消了 「Break」 鍵,在這種狀況下你不得不用谷歌搜索與 Break 鍵功能相似的鍵,我發現 「Function key + B」 鍵與 Break 鍵的功能相同,所以我用 「Ctrl + Fn + B」 鍵來生成 dump 文件。
注意2: 用上述方式有一個缺點就是 dump 文件的內容會被打印到控制檯上,沒有 dump 文件的話,咱們很難用分析工具好比http://fasthread.io來分析 dump 文件。所以你可使用如下命令將 dump 文件的內容輸出到文本文件當中,好比你的應用程序名字叫 SampleThreadProgram ,那麼一般使用的命令以下:
java -classpath . SampleThreadProgram
將 dump 文件的內容輸出到文本文件的命令以下:
java -classpath . SampleThreadProgram > C:\workspace\threadDump.txt 2>&1
當你按下 「Ctrl + Break」 鍵以後,dump 文件會被保存到 C:\workspace\threadDump.txt 裏。
從 JDK 1.5 開始,ThreadMXBean 被引入。這是 JVM 的管理接口,使用這個接口你僅須要少許的代碼就能生成 dump 文件,如下是使用 ThreadMXBean 生成 dump 文件的主要實現:
public void dumpThreadDump() { ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean(); for (ThreadInfo ti : threadMxBean.dumpAllThreads(true, true)) { System.out.print(ti.toString()); } }
一些應用性能監控工具提供了生成 dump 文件的功能,若是你使用 App Dynamics 監控你的應用,如下就是生成 dump 文件的步驟:
打開建立動做窗口,在建立動做窗口中選擇 Diagnostics->Take a thread dump;
輸入動做名稱、抓取 dump 文件的數量、抓取 dump 文件的時間間隔(毫秒);
若是你想在抓取 dump 動做開始以前執行一些操做,那麼你能夠選中 Require approval executing before this Action
這個複選框,而後輸入我的或小組的 email 地址;
點擊 OK.
儘管我在前面列出了7種抓取 dump 文件的方式,但恕我直言,jstack
和 kill -3
是最好的選擇,緣由以下:
a. 簡單,容易實現;
b. 通用:在大多數狀況下,無論操做系統類型、Java 廠商、JVM 版本等等。
編譯自:https://dzone.com/articles/how-to-take-thread-dumps-7-options