Java 性能診斷工具簡介
在 Java 的世界里,有許多診斷工具可供選擇,既包括像 jmap、jstat 這樣的簡單命令行工具,又包括 JVisualvm、JProfiler 等圖形化綜合診斷工具,同時還有 SkyWalking、ARMS 這樣的針對分布式應用的性能監控系統。
簡單命令行工具
JDK 內置了許多命令行工具,它們可用來獲取目標 JVM 不同方面、不同層次的信息。
- jinfo - 用於實時查看和調整目標 JVM 的各項參數。
- jstack - 用於獲取目標 Java 進程內的線程堆棧信息,可用來檢測死鎖、定位死循環等。
- jmap - 用於獲取目標 Java 進程的內存相關信息,包括 Java 堆各區域的使用情況、堆中對象的統計信息、類加載信息等。
- jstat - 一款輕量級多功能監控工具,可用於獲取目標 Java 進程的類加載、JIT 編譯、垃圾收集、內存使用等信息。
- jcmd - 相比 jstat 功能更為全面的工具,可用於獲取目標 Java 進程的性能統計、JFR、內存使用、垃圾收集、線程堆棧、JVM 運行時間等信息。
圖形化綜合診斷工具
使用上述命令行工具或組合能幫您獲取目標 Java 應用性能相關的基礎信息,但它們存在下列局限:
- 無法獲取方法級別的分析數據,如方法間的調用關系、各方法的調用次數和調用時間等(這對定位應用性能瓶頸至關重要)。
- 要求用戶登錄到目標 Java 應用所在的宿主機上,使用起來不是很方便。
- 分析數據通過終端輸出,結果展示不夠直觀。
JVisualvm
JVisualvm 是 JDK 內置的可視化性能診斷工具,它通過 JMX、jstatd、Attach API 等方式獲取目標 JVM 的分析數據,包括 CPU 使用率、內存使用量、線程堆棧信息等。此外,它還能直觀地展示 Java 堆中各對象的數量和大小、各 Java 方法的調用次數和執行時間等。
JProfiler
JProfiler 是一款 Java 應用性能診斷工具。它聚焦於四個重要主題上。
- 方法調用 - 對方法調用的分析可以幫助您了解應用程序正在做什么,並找到提高其性能的方法。
- 內存分配 - 通過分析堆上對象、引用鏈和垃圾收集能幫您修復內存泄漏問題,優化內存使用。
- 線程和鎖 - JProfiler 提供多種針對線程和鎖的分析視圖助您發現多線程問題。
- 高級子系統 - 許多性能問題都發生在更高的語義級別上。例如,對於JDBC調用,您可能希望找出執行最慢的 SQL 語句。JProfiler 支持對這些子系統進行集成分析。
分布式應用性能診斷
如果只需要診斷單機 Java 應用的性能瓶頸,上面介紹的診斷工具就已經夠用了。但隨着現代系統架構逐漸從單體轉變為分布式、微服務,單純使用上述工具往往無法滿足需求,這時就需要借助 Jaeger、ARMS、SkyWalking 這些分布式追蹤系統提供的全鏈路追蹤功能。分布式追蹤系統種類繁多,但實現原理都大同小異,它們通過代碼埋點的方式記錄 tracing 信息,通過 SDK 或 agent 將記錄的數據傳輸至中央處理系統,最后提供 query 接口對結果進行展示和分析。
JProfiler簡介
JProfiler是一款性能瓶頸分析工具,其特點:
- 使用方便
- 界面操作友好
- 對被分析的應用影響小
- CPU,Thread,Memory分析功能尤其強大
- 支持對jdbc,noSql, jsp, servlet, socket等進行分析
- 支持多種模式(離線,在線)的分析
- 跨平台
下載地址:http://www.sd173.com/soft/10427.html
鏈接:https://pan.baidu.com/s/1WXCc4FMOC3QQtjkhY4Qeow
提取碼:5xrm
版本:JProfiler 12.0.4
JProfiler功能介紹
功能面板介紹
1、Telemetries(遙測)
2、Live memory (實時內存)
JProfiler 的內存視圖部分可以提供動態的內存使用狀況更新視圖和顯示關於內存分配狀況信息的視圖。所有的視圖都有幾個聚集層並且能夠顯示現有存在的對象和作為垃圾回收的對象。
- All Objects 所有對象:顯示所有加載類的列表和堆上分配的實例數。在最上方還可以選擇按不同類型進行查看,如類、包、組件等。
- Record objects 記錄的對象 :顯示類或所有已記錄對象的包。你可以標記出當前值並且顯示差異值。
- Allocation call tree 分配調用樹 :是顯示請求樹或者方法、類、包或對已選擇類有帶注釋的分配信息的J2EE組件。
- Allocation hot spots 分配熱點 :顯示所選類的對象被分配在哪兒的方法列表。注意:分配至少占總數的1%的方法才會被顯示。
- Class Tracker 類追蹤器
3、Heap walker (堆遍歷器)
在JProfiler的堆遍歷器(Heap walker)中,你可以對堆的狀況進行快照並且可以通過選擇步驟下尋找感興趣的對象。堆遍歷器有七個視圖:
- Classes 類 :顯示所有類和它們的實例。
- Allocations 分配 :為所有記錄對象顯示分配樹和分配熱點。
- Biggest Objects 大對象:顯示占用內存多的對象
- References 引用 :為單個對象和“顯示到垃圾回收根目錄的路徑”提供索引圖的顯示功能。還能提供合並輸入視圖和輸出視圖的功能。
- Time 時間 :顯示一個對已記錄對象的解決時間的柱狀圖。
- Inspections 檢查
- Graph 圖表
4、CPU views (CPU視圖)
JProfiler 提供不同的方法來記錄訪問樹以優化性能和細節。線程或者線程組以及線程狀況可以被所有的視圖選擇。所有的視圖都可以聚集到方法、類、包或J2EE組件等不同層上。CPU視圖部分包括:
- Call tree 訪問樹:顯示一個積累的自頂向下的樹,樹中包含所有在JVM中已記錄的訪問隊列。JDBC,JMS和JNDI服務請求都被注釋在請求樹中。請求樹可以根據Servlet和JSP對URL的不同需要進行拆分
- Hot spots 熱點 :顯示消耗時間最多的方法的列表。對每個熱點都能夠顯示回溯樹。該熱點可以按照方法請求,JDBC,JMS和JNDI服務請求以及按照URL請求來進行計算。
- Call graph 調用圖 :顯示一個從已選方法、類、包或J2EE組件開始的訪問隊列的圖。
- Call Tracer 調用跟蹤器
- JavaScript XHR
5、Threads (線程)
對線程剖析,JProfiler提供以下視圖:
(1) Thread history 線程歷史:默認的就是歷史視圖,在這里可以觀察到程序中所使用的線程歷史記錄。不同的顏色代表不同意義。
- 綠色表明線程正在運行並能接收CPU時間,不表明線程正在消耗CPU時間,只表明線程准備運行並且沒有阻塞或睡眠。線程被分配了多少CPU時間,依賴於不同的其它元素,如總的系統負載,線程優先級和調度的運算法則。
- 橙色表示線程正在等待。線程正在睡眠並等待計時器或其它線程喚醒
- 紅色表示線程阻塞。線程嘗試進入同步代碼塊或有其它線程控制的同步方法
- 亮藍色表示線程正在Net I/O操作,線程在等待Java庫的網絡操作完成。在線程監聽socket連接或者等待讀寫數據到socket中時,會產生這種狀態。
(2) Thread monitor 線程Monitor
使用監控當前線程時要注意:如果你監控的是Java1.5或以上版本,屏幕的上半部分就顯示線程 列表,屏幕的下半部分顯示所選線程的線程創建堆棧跟蹤。堆棧跟蹤只有線程創建時記錄CPU數據才會顯示。
(3) Thread dumps 監控死鎖
死鎖根據以下情況進行分析:
- 在Java平台上建立的最初的同步機制,如:使用同步的關鍵詞。
- 在java.util.concurrent中的鎖機制,不使用對象的監控,而是不同的實現機制。
- 在死鎖中的線程以紫色的矩形表示
- 在死鎖中的監視器以灰色的矩形表示
- 監控器的所有權用實線箭頭表示
- 導致線程死鎖的阻塞原因使用虛線箭頭來表示
深入分析線程,可以在"Monitors & locks"中查看。
6、Monitors & locks (Monitor&鎖)
- Current Locking Graph 當前鎖狀態圖
- Current Monitors 目前使用的監測器:顯示目前使用的監測器並且包括它們的關聯線程。
- Locking History Graph 鎖狀態歷史圖
- Monitor History 歷史檢測記錄:顯示重大的等待事件和阻塞事件的歷史記錄。
- Monitor Usage Statistics 監測使用狀態 :顯示分組監測,線程和監測類的統計監測數據。
7、Databases (數據庫)
8、JEE & Probes(JEE&探針)
9、MBeans
Jprofiler創建工程
1、使用jprofiler自帶的例子工程
JProfier采集方式分為兩種:Sampling(樣本采集)和Instrumentation
- Sampling: 類似於樣本統計, 每隔一定時間(5ms)將每個線程棧中方法棧中的信息統計出來。優點是對應用影響小,缺點是一些數據/特性不能提供(例如:方法的調用次數)
- Instrumentation: 在class加載之前,JProfier把相關功能代碼寫入到需要分析的class中,對正在運行的jvm有一定影響。優點: 功能強大,但如果需要分析的class多,那么對應用影響較大,一般配合Filter一起使用。所以一般JRE class和framework的class是在Filter中通常會過濾掉。
2、創建一個監視本地服務的jprofiler工程
結合開發工具idea即可。
① 首先給自己電腦下載JProfiler軟件,記錄你的安裝目錄;
② 給idea安裝JProfiler的插件
③ 安裝好后重啟idea,給idea配置JProfiler的執行程序,如下圖,這里選擇你自己本地安裝的JProfiler軟件安裝目錄bin里的.exe;點擊apply;
④ 點擊下圖中圈出的按鈕,運行你的項目,就會啟動你的 JProfiler,對項目運行狀況進行實時監測分析
3、創建一個監視遠程服務的jprofiler工程
JProfiler如何使用
Live memory 分析內存情況
1、在這里可以查看程序使用內存的情況,如果發現自己的方法在這里占有內存很大或是在某個時間段突然增加,就可以關注這個類或方法,是不是在寫這個方法時用了占用大量內存的手法。在這里還可以跟蹤到類源代碼和byte code。
2、這里在系統運行后可以使用按鈕,以當前為參照對象,動態的觀察內存使用變化。其中綠色為參考時間點,褐色為當前時間的內存使用情況。這樣就可以觀察內存的使用,對象的創建和gc的使用情況等。
3、數量監控很重要,如果你使用了單例,那么你只會看到有一個對象存在,如果多了就說明程序有問題。同樣,如果應用進行了一系列的操作,檢查一下該銷毀的對象是否還繼續存在,如果沒有釋放,就得考慮是否存在內存溢出了。
Heap walker分析堆遍歷
可以查找某個對象的引用情況,即:當你發現某個該釋放的對象沒有釋放,就可以看下哪個實例在引用它,找到了根即找到了溢出點。在“Live memory”界面中右鍵選擇你要監控的對象,選擇第一項"Take Heap Snapshot for Selection"(在堆遍歷器中顯示所選內容),選擇完成后會進入"Heap walker"界面,然后選擇頂部的"References"(引用)即可。
CPU views 分析CPU情況
在這里可以觀察某個時間段內方法對於cpu的使用情況,如果某個方法對cpu長時間的高頻率占有,那程序肯定會慢,這時就要檢查該方法是否有什么非常耗時的計算。例如:在使用swing的事件線程中進行了復雜運算,長時間占有cpu,這時就要考慮對事件進行多線程操作等。
Threads 分析線程情況
使用死鎖分析可以很快的進行線程邏輯定位,直觀圖形化可以使用死鎖的原因一目了然。另外可以在"Monitors & locks"里的"Monitor usage statistics"(Monitor使用情況統計)進行線程操作頻繁度統計,能很好的幫助對程序進行的理解和性能分析。
JProfiler分析案例