使用 VPA 快速定位 Java 應用性能瓶頸
簡介:大型 Java 應用調用了大量的類和方法,如何在這成千上萬行的代碼中找到應用的性能瓶頸呢 ?在本文中,作者將介紹如何為不同的性能問題選擇性能分析工具,對性能問題采樣以及使用 Visual Performance Analyzer 分析性能采樣結果並快速定位性能瓶頸。
引言
類是 Java 的基礎。大規模的 Java 應用是由成千上萬個類構成的。當出現性能問題時,如何才能在 這一大堆類中迅速定位性能瓶頸呢?更糟糕的是,有些類是由某個同事在上個世紀編寫的,某些類是第三 方提供的,沒有人明白這些類給整個應用帶來了怎樣的性能影響。
關於 VPA
VPA(Visual Performance Analyzer)是基於 Eclipse 開發的可視化性能分析工具集。
VPA 為性能分析提供了六件武器:Profile Analyzer、Code Analyzer、 Pipeline Analyzer、 Counter Analyzer、 Trace Analyzer、 Call Tree Analyzer。每個工具可以用於分析一種特定類別的性 能數據。
如果您想進一步了解 VPA,您可以參考 VPA 用戶指南。
VPA 中的兩個工具:Profile Analyzer 和 CallTree Analyzer,對 Java 應用程序的性能分析提供了 有力的支持。這兩個工具提供了多個視圖,幫助用戶從不同的角度分析性能數據。通過這兩個工具幫助, 用戶可以快速地從這成千上萬行的代碼中找到性能最差的方法或者代碼行。
使用 VPA 分析性能問題的過程可以分為三步:
針對不同性能問題,選擇恰當的性能分析工具;
采集性能數據;
使用 VPA 分析性能數據;
本文將以小程序 bookstore 為例,介紹如何使用這兩個工具快速定位性能問題。
小程序 bookstore
bookstore 是個基於 AWT 的圖形界面程序。它讀取圖書索引文件到內存中,然後列出文件中包含的所 有圖書分類。如果用戶在分類列表中選中某個圖書分類,圖書列表中會列出所有該分類下的圖書。圖 1 是小程序 bookstore 圖形界面的截圖。
圖 1. bookstore 小程序
bookstore 小程序有兩點性能問題:
打開比較大的圖書索引文件需要比較長的等待時間。
如果用戶選中一個分類,bookstore 小程序會很長時間不響應,並且 100% 地占用 CPU 資源。
選擇恰當的性能分析工具
Java 應用的性能問題多種多樣,有 IO 方面的,也有處理器資源方面的。針對不同的性能問題,性能 分析師需要使用不同的采樣手段和分析工具。VPA 中有兩個工具可以用於分析 Java 應用的性能問題: Profile Analyzer 和 Call Tree Analyzer。它們適用於不同的性能問題。
Call Tree Analyzer 可以幫助用戶找到耗時最長的方法以及該方法的所有調用堆棧,對所有與速度相 關的性能問題都適用。
Profile Analyzer 則對於那些和處理器資源密切相關的性能問題(比如 CPU 利用率 100%)有比較強 的針對性。
Profile Analyzer
Profile Analyzer 被用於分析抽樣數據。抽樣采樣時,系統每隔一定周期,采樣一次,采集當前正在 運行的指令的地址、線程號和進程號。根據被抽樣到的概率不同,可以知道哪些進程、線程、指令消耗了 最多的處理器資源。除此之外 , 抽樣采樣給應用造成的額外開銷比較小。Profile Analyzer 為抽樣采樣 數據的分析提供了一系列的文字或者圖形的視圖。通過這些視圖,分析師可以將性能瓶頸定位到進程、線 程、類、方法甚至具體的代碼。
小程序 booksotre 的第二個性能問題是 CPU 資源相關的性能問題,通過 Profile Analyzer 可以迅 速找到占用處理器資源最多的代碼。
Call Tree Analyzer
Call Tree Analyzer 被用於分析方法調用追蹤數據。方法調用追蹤數據中記錄了方法調用堆棧和方法 調用的起始時間。方法調用追蹤數據可以用於分析各種速度相關的性能問題。 Call Tree Analyzer 將方 法調用追蹤數據以方法調用樹的形式展現出來。通過對方法調用樹的分析,用戶不僅可以找到自身調用時 間最長、總調用時間最長的方法,還可以根據這些方法的調用堆棧了解到性能瓶頸形成的原因。
小程序 bookstore 的第一個性能問題有可能是 IO 問題,Profile Analyzer 不適用於這樣的問題, 可以用 Call Tree Analyzer 來尋找性能瓶頸。
性能采樣
VPA 支持多種不同格式的性能數據。表 1 中列出了 VPA 支持的 VPA 支持的性能數據格式。這裡以小 程序"bookstore"為例,介紹如何通過 Performance Inspector 采集抽樣數據和方法調用樹。
表 1. VPA 支持的性能數據格式
配置環境變量
使用 Performance Inspector 采集性能數據,首先需要告訴采樣工具相關的環境變量。
清單 1. 設置環境變量
> cd /d c:\ibmperf\bin
> setrunenv
采集抽樣結果
TPROF 是 Performance Inspector 提供的抽樣采樣工具。TPROF 允許用戶只采集某一段時間的抽樣。 使用 TPROF 對 bookstore 小程序采樣時,
首先啟動 TPROF,如清單 2,執行"run.tprof"命令
清單 2. 啟動 TPROF
> cd /d c:\ibmperf\bin
> setrunenv
> run.tprof
然後,如清單 3,打開另外一個命令行窗口,執行命令 java -Xjit:enableJVMPILineNumbers - Xrunjprof:tprof,fnm=C:\ibmperf\bin\log,pidx-jar bookstore.jar,啟動 bookstore 小程序。
清單 3. runjprof:tprof
> cd /d c:\ibmperf\bin
> setrunenv
> java -Xjit:enableJVMPILineNumbers \
-Xrunjprof:tprof,fnm=C:\ibmperf\bin\log,pidx \
-jar bookstore.jar
打開圖書索引文件。
選中圖書分類的第一項後,立即在 TPROF 的命令行窗口中敲下回車鍵。TPROF 開始采樣。
小程序恢復響應並顯示圖書列表後,在 TPROF 的命令行窗口中敲下回車鍵。TPROF 結束采樣。
采樣結束後,執行命令"mergetprof",將代碼行等信息合並到抽樣采樣數據中。
在 Performance Inspector 安裝目錄的 bin 文件夾下生成了"tprof_e.out”文件。這個文件就是可 以被 Profile Analyzer 讀取的抽樣采樣數據。
采集方法調用樹
JPROF 是 Performance Inspector 中的一個工具,可以通過 JVMTI 或 JVMPI 接口紀錄方法的調用信 息。對 bookstore 采集方法信息時,
首先,如清單 4 執行,命令 java -Xrunjprof:callflow,raw_cycles,start-jar bookstore, 啟動 bookstore。
清單 4. runjprof:calltree
> cd /d c:\ibmperf\bin
> setrunenv
> java -Xrunjprof:callflow,raw_cycles,start -jar bookstore.jar
然後,打開圖書索引文件。
文件讀取結束後,關閉 bookstore 小程序。
在當前目錄生成了一個 log-rt.xxx文件。將這個文件重命名為 log-rt.xxx.jprof,Call Tree Analyzer 就可以打開這個 Call Tree 文件。
分析采樣結果
使用 VPA 打開采樣數據文件,VPA 會根據性能數據的文件類型,自動打開相應的性能分析工具。VPA 提供了大量圖型的和文字的視圖,幫助用戶從不同角度分析性能采樣。
分析抽樣結果
使用 Profile Analyzer 分析 Java 程序的性能問題時,編輯器、Source Code 視圖和 Java Hierarchy 視圖是比較常用的控件。
編輯器可以幫助用戶找到 Ticks 最多的方法。如圖 2,tprof_e.out 打開後,編輯器按照"Process > Module"或者"Process > Thread >Module"等不同分層模式以樹狀結構列出了采樣到的進程、 線程和模塊。JITCODE 模塊是 Java 進程中 Ticks 最多的模塊,而 BestAuthor$1.valueChanged 方法是 JITCODE 模塊中 Ticks 最多的方法。
圖 2. Profile Analyzer 的編輯器
Source Code 視圖可以幫助用戶找到 Ticks 最多的代碼行。在編輯器中雙擊方法 BestAuthor$1.valueChanged,VPA 會彈出對話框詢問這個方法相應的源文件。如圖 3,為方法 BestAuthor$1.valueChanged 指定源文件後,通過 Source Code 視圖,可以找到 Ticks 最多的代碼行。 這樣的代碼行很有可能是程序的性能瓶頸。
圖 3. Source Code 視圖
通過"Java Hierarchy"視圖,用戶可以按照 Java 方法所屬的包和類逐層浏覽這些被采集到的 Java 方法。如圖 4,Java Hierarchy 視圖的右側表格中列出了包 bookstore.ui 下所有被采樣到的方法。
圖 4. Java Hierarchy 視圖
分析方法調用樹
Call Tree Analyzer 提供了編輯器、Method Overview 視圖、Call Stack 視圖等控件。
如圖 5,編輯器以方法調用樹和執行圖的方式來展現 JProf 文件。
圖 5. 方法調用樹和執行圖
"Method Overview"視圖列出了方法調用樹中所有的方法。如圖 6,點擊 RAW_CYCLES 列,"Method Overview"按照方法自身消耗時間長短對方法列表進行排序。方法自身消耗時間很長的方法很有可能是性 能瓶頸。
圖 6. Method Overview 視圖
在"Method Overview"視圖中,雙擊 BookReader.startElement 方法,Call Stack 視圖會顯示 BookReader.startElement 方法的調用堆棧。通過圖 7 中的調用堆棧,用戶可以了解到 BookReader.startElement 方法是怎樣被調用的。
圖 7. Call Stack 視圖
在"Call Stack"視圖中,雙擊 BookReader.startElement 方法,可以在 Call Tree 中定位到這個方 法。如圖 8,用戶通過浏覽 Call Tree,可以更清楚地了解 BookReader.startElement 方法的上下文。
圖 8. 在 Call Tree 中定位 BookReader.startElement 方法,
下載