1. 程式人生 > >[轉載] 常用 Java Profiling 工具的分析與比較

[轉載] 常用 Java Profiling 工具的分析與比較

原文: [url]http://www.ibm.com/developerworks/cn/java/j-lo-profiling/[/url]

原作者:
周 鵬, CSTL 軟體工程師, IBM
周鵬,CSTL 軟體工程師,從事過三年 Mainframe 上系統軟體的開發,一年 Director6.1 在 IBM pSeries 的測試工作以及測試環境的維護工作。目前負責 Director6.1 與其他產品,如 IBM Tivoli, HP OVO, CA NSM 等的整合開發工作。
徐 曉琴, 軟體工程師, Verigy


[u][b]簡介:[/b][/u]
在 Java 程式的開發過程中,不可避免地會遇到記憶體使用、效能瓶頸等問題。Java Profiler 工具能幫助開發人員快速、有效地定位這些問題,因此成為了 Java 開發過程中的一個重要工具。目前市場上的 Java Profiler 工具種類繁多,本文將對目前比較常見的幾種工具進行簡要介紹,並從功能、效能等角度作比較,從而幫助 Java 程式設計師選擇合適的 Java Profiler 工具。

本文主要分為三個部分:第一部分簡要介紹 Java Profiler 工具的原理;第二部分對目前常見的 Java Profiler 工具 TPTP, CodePro Profiler, YourKit Java Profiler, JProfiler 進行簡要介紹;第三部分對以上工具從不同的角度進行比較,幫助開發人員選擇合適的工具。

[i][b]原理[/b][/i]
相對於靜態程式碼分析,Profiling 是通過收集程式執行時的資訊來研究程式行為的動態分析方法。其目的在於定位程式需要被優化的部分,從而提高程式的執行速度或是記憶體使用效率。收集程式執行時資訊的方法主要有以下三種:

事件方法:對於 Java,可以採用 JVMTI(JVM Tools Interface)API 來捕捉諸如方法呼叫、類載入、類解除安裝、進入 / 離開執行緒等事件,然後基於這些事件進行程式行為的分析。
統計抽樣方法(sampling): 該方法每隔一段時間呼叫系統中斷,然後收集當前的呼叫棧(call stack)資訊,記錄呼叫棧中出現的函式及這些函式的呼叫結構,基於這些資訊得到函式的呼叫關係圖及每個函式的 CPU 使用資訊。由於呼叫棧的資訊是每隔一段時間來獲取的,因此不是非常精確的,但由於該方法對目標程式的干涉比較少,目標程式的執行速度幾乎不受影響。
植入附加指令方法(BCI): 該方法在目標程式中插入指令程式碼,這些指令程式碼將記錄 profiling 所需的資訊,包括執行時間、計數器的值等,從而給出一個較為精確的記憶體使用情況、函式呼叫關係及函式的 CPU 使用資訊。該方法對程式執行速度會有一定的影響,因此給出的程式執行時間有可能不準確。但是該方法在統計程式的執行軌跡方面有一定的優勢。
目前市面上的 Java Profiler 工具採用的資訊收集方法通常是以上三種方法的任意組合。

[i][b]Profiler 工具功能簡介[/b][/i]
雖然市場上的 Java Profiler 工具有不少,但是基本功能大多相似,本節首先對這些基本功能進行介紹。

[b]遙測(Telemetry):[/b]遙測是一種用來檢視應用程式執行行為的最簡單的方法。通常會有多個檢視(View)分別實時地顯示 CPU 使用情況、記憶體使用情況、執行緒狀態以及其他一些有用的資訊,以便使用者能很快地發現問題的關鍵所在。
[b]CPU Telemetry 檢視[/b]一般用於顯示整個應用程式的 CPU 使用情況,有些工具還能顯示應用程式中每個執行緒的 CPU 使用情況。
[b]Memory Telemetry 檢視[/b]一般用於顯示堆記憶體和非堆記憶體的分配和使用情況。
[b]Garbage Collection Telemetry 檢視[/b]顯示了 JVM 中垃圾收集器的詳細資訊。
[b]Threads Telemetry 檢視[/b]一般用於顯示當前執行執行緒的個數、守護程序的個數等資訊。
[b]Classes Telemetry 檢視[/b]一般用於顯示已經載入和還沒有載入的類的數量。

[b]快照(snapshot):[/b]應用程式啟動後,profiler 工具開始收集各種執行資料,其中一些資料直接顯示在遙測檢視中,而另外大部分資料被儲存在內部,直到使用者要求獲取快照,基於這些儲存的資料的統計資訊才被顯示出來。快照包含了應用程式在一段時間內的執行資訊,通常有兩種型別的快照:CPU 快照和記憶體快照。
[b]CPU 快照[/b]主要包含了應用程式中函式的呼叫關係及執行時間,這些資訊通常可以在 CPU 快照檢視中進行檢視。
[b]記憶體快照[/b]則主要包含了記憶體的分配和使用情況、載入的所有類、存在的物件資訊及物件間的引用關係。這些資訊通常可以在記憶體快照檢視中進行檢視。


[b]CPU Profiling[/b]:CPU Profiling 的主要目的是統計函式的呼叫情況及執行時間,或者更簡單的情況就是統計應用程式的 CPU 使用情況。通常有兩種方式來顯示 CPU Profiling 結果:CPU 遙測和 CPU 快照。

[b]記憶體 Profiling[/b]:記憶體 Profiling 的主要目的是通過統計記憶體使用情況檢測可能存在的記憶體洩露問題及確定優化記憶體使用的方向。通常有兩種方式來顯示記憶體 Profiling 結果:記憶體遙測和記憶體快照

[b]執行緒 Profiling[/b]:執行緒 Profiling 主要用於在多執行緒應用程式中確定記憶體的問題所在。 一般包括三個方面的資訊:
某個執行緒的狀態變化情況
死鎖情況
某個執行緒線上程生命期內狀態的分佈情況

[b]Profiling 的啟動設定[/b]:類似於 eclipse 中 Run 和 Debug 的啟動設定,進行 Profiling 之前也需要進行啟動設定,包括:profiling 的模式 (CPU profiling 或記憶體 profiling),資訊獲取型別(遙測 , 抽樣統計或者 BCI ) 等等。

[b]Profiler Preference 設定[/b]:主要用於 Profiler 過濾器(選擇需要關注的包、類)、取樣間隔時間的設定等。


[i][b]Java Profiler 工具介紹[/b][/i]
本文接下來將對目前市場上常見的幾種 Java Profiler 工具進行介紹

[b]TPTP[/b]

TPTP(Test and Performance Tools Platform)是 eclipse 官方的 Profiling 工具外掛。TPTP 提供了諸如測試,追蹤(trace),效能測試,圖形介面效能分析等功能。同時 TPTP 還是一個可擴充套件的開發平臺框架,你可以對它加以擴充套件整合到你自己的產品中。TPTP 可以通過 Eclipse update Manager 或者是安裝包進行安裝,安裝成功後會在 eclipse 中增加如下所示的按鈕,另外一個專門的用於檢查 TPTP profiling 結果的 perspective 也會新增進 eclipse 中,如下圖所示:

[b]圖 1. TPTP[/b][img]http://dl.iteye.com/upload/attachment/302804/32140491-4f6a-39a3-9e5f-e66042c3f343.bmp[/img]


[b]CodePro Profiler[/b]

CodePro Profiler 是由 instantiations 公司推出的一款商用 eclipse 外掛,它可以通過 Eclipse update Manager 進行安裝或者是將安裝包直接解壓縮後儲存在 eclipse 的指定目錄下。與 TPTP 類似,安裝成功後,有一個專門的用於檢視 CodePro profiling 結果的 perspective 會新增進 eclipse 中,如下圖所示:


[b]圖 2. CodePro[/b]
[img]http://dl.iteye.com/upload/attachment/302808/a12266ae-dfa9-382f-b21d-9355722a5a40.bmp[/img]

[b]YourKit Profiler[/b]

YourKit Java Profiler 也是一款商用軟體,支援的作業系統包括:Windows, Linux, FreeBSD, Mac OS X, Solaris 以及 HP-UX;支援的 IDE 包括:Eclipse, JBuilder, JDeveloper, NetBeans 以及 Intellij IDEA。安裝成功且首次啟動 YourKit Java Profiler 後,會彈出一個對話方塊,讓使用者選擇 YourKit Java Profiler 要整合進的 IDE,並指定該 IDE 的安裝路徑,點選”Install Plugin”按鈕並整合成功之後,Eclipse 中會出現如下圖示,使用者就可以從 Eclipse 中啟動 Profiling,但是 profiling 的結果需要在 YourKit Java Profiler 中進行查詢,如下圖所示:


[b]圖 3. YourKit[/b]
[img]http://dl.iteye.com/upload/attachment/302810/ad43257c-887c-347a-a890-0e4f56315c96.bmp[/img]

[b]JProfiler[/b]

JProfiler 是由 ej-technologies 推出的一款商用軟體,支援的作業系統有:Windows, Linux, Mac OS X, FreeBSD, Solaris, AIX 以及 HP-UX;支援的 IDE 包括:Eclipse, NetBeans, Intellij IDEA, JBuiler 以及 JDeveloper。安裝成功並首次啟動 JProfiler 後,會彈出一個設定介面,當完成左欄所示的那些步驟後,Eclipse 中就會出現如下圖示,使用者就可以從 Eclipse 中啟動 Profiling。與 YourKit Java Profiler 類似,profiling 的結果需要在 JProfiler 中進行查詢,如下圖所示:

[b]圖 4. JProfiler[/b]
[img]http://dl.iteye.com/upload/attachment/302812/f2eac594-ba44-3342-b8ff-d6e2d048ab73.bmp
[/img]


[i][b]Java Profiler 工具比較[/b][/i]

本章節將從如下幾個方面對上述工具進行比較:

[b]與 Eclipse 的整合性[/b]
[list]
[*] TPTP:是一款基於 Eclipse 開發的外掛,因此與 eclipse 的整合性很好。安裝成功後,對 TPTP 的一切設定與操控都可以在 eclipse 中完成;另外,profiling 的結果也可以在 eclipse 中進行查詢。

[*]CodePro Profiler: 與 TPTP 類似,CodePro Profiler 也是一款基於 eclipse 開發的外掛,因此與 eclipse 的整合性很好好。使用者在 eclipse 中就可以完成對 profiling 的所有操作。

[*]YourKit Java Profiler: YourKit Java Profiler 可以說是一個比較獨立的工具,安裝成功後,使用者可以直接在 eclipse 中啟動 YourKit Java Profiler 並對 profiling 選項進行配置,但是使用者必須在 YourKit Java Profiler 工具中對 Profiling preferrence 進行配置,而且 profiling 資訊必須在 YourKit Java Profiler 中進行檢視。因此和 Eclipse 的整合度一般。

[*]JProfiler: JProfiler 也是一款比較獨立的工具,安裝成功後,使用者可以直接在 eclipse 中啟動 JProfiler,其他所有操作必須回到 JProfiler 工具中進行。因此和 Eclipse 的整合性不好。

[/list]

[b]遙測種類 [/b]

[list]
[*] TPTP:目前使用的 4.6.2 的版本只提供了執行緒 Telemetry。
[*] CodePro Profiler: 總共有五個型別:CPU, 記憶體 , 執行緒 , 載入的類以及垃圾收集。
[*] YourKit Java Profiler: 與 CodePro Profiler 相比,缺少載入類的監測。
[*] JProfiler: 與 CodePro Profiler 一樣,總共有五個型別的監測方法。
[/list]

[b]CPU 快照包含的統計資料型別[/b]
[list]
[*] TPTP: CPU 快照包含的統計資料有:
包的組成關係,細化到包含的類及類中的方法。

方法的呼叫關係:以每個執行緒為根節點的方法呼叫資訊,對於樹中出現的代表方法的每個節點,列出了該方法的執行時間或執行時間百分比,以及該方法被呼叫的次數。

方法被呼叫情況:列出了直接呼叫某方法的其他方法,以及這些方法呼叫該方法的次數及相關執行時間。

熱點列表:包含了 CPU 佔用時間排列前十的方法、類或包。
[*]CodePro Profiler: CPU 快照包含的統計資料型別有:
包的組成關係,細化到包含的類及類中的方法。

方法的呼叫關係。以樹結構表示,根據根節點表示的物件的不同,分為三種類型:以每個執行緒為根節點的方法呼叫關係,以整個執行緒為根節點的方法呼叫關係,以及以每個方法為根節點的方法呼叫關係。對於樹中出現的代表方法的每個節點,列出了該方法的執行時間或執行時間百分比,以及由該方法生成的物件個數和為這些物件分配的記憶體大小。
方法的被呼叫關係。該關係以樹結構表示,其中根節點為某個指定的方法,每個節點的子節點為父節點的呼叫者。

熱點列表:包含了 CPU 佔用時間排前的一些方法。
[*]YourKit Java Profiler:CPU 快照包含的統計資料型別與 CodePro Profiler 類似;
[*]JProfiler:與 CodePro Profiler 相比,缺少以每個方法為根節點的方法呼叫關係。因此當要檢視以某個方法為呼叫起點的呼叫關係時,需要到以執行緒為根的樹結構當中去查詢。另外,方法的被呼叫關係不是以樹結構來表示的,而是以圖的方式來顯示的,當呼叫關係比較複雜的時候,很難在一個螢幕中看到一個全域性關係圖。
[/list]

[b]記憶體快照包含的統計資料型別 [/b]

[list]
[*]TPTP:包含了類例項的記憶體分配情況,包括例項化的物件個數,以及這些物件的本身佔用記憶體的大小。相對於其它 Java Profiler 工具,TPTP 的記憶體快照包含的統計資料型別比較少。
[*]CodePro Profiler: 包含的統計資料有
類例項的記憶體分配情況,包括例項化的物件個數,以及這些物件的 shallow 和 retained 大小。(Shallow size 就是物件本身佔用記憶體的大小,不包含對其他物件的引用;Retained size 是該物件自己的 shallow size,加上從該物件能直接或間接訪問到的 shallow size 之和,即該物件被 GC 之後所能回收到記憶體的總和)。

最大物件列表:包含了 retained 大小排前的一些物件。

有可能存在記憶體洩漏的物件列表:包含了有可能存在記憶體洩漏的物件以及可能性大小。

[*] YourKit Java Profiler:與 CodePro Profiler 相比,缺少記憶體洩露物件列表這一項
[*] JProfiler:與 CodePro Profiler 相比,缺少 retained size 統計資料及記憶體洩露物件列表。

[/list]

[b]原始碼定位功能,即在快照中選中某個類、成員變數或者方法時,可以在原始碼中定位到對應的定義。[/b]

[list]
[*]TPTP:只能定位到某個類,無法定位到方法或其中的成員變數。
[*]CodePro Profiler: 擁有該功能,但是隻能定位到類及成員變數,無法定位到方法
[*]YourKit Java Profiler:可以定位到類、成員變數及方法。
[*]JProfiler:與 CodePro Profiler 類似
[/list]

[b]快照操作,主要從快照的獲取、快照的儲存及快照的比較這三方面進行比較。[/b]

[list]
[*]TPTP:當應用程式啟動後,使用者可以選擇在適當的時候進行快照獲取;這些快照不會自動儲存,因此當 eclipse 關閉後,這些快照資料將會消失,但是使用者可以通過 export 的方式將需要的快照儲存下來。
[*]CodePro Profiler: 當應用程式啟動後,使用者可以選擇在適當的時候進行快照獲取;這些快照會被自動儲存在 Eclipse Workspace 之外的一個臨時的空間,當 eclipse 關閉後,這些快照將會消失,使用者可以通過 export 的方式將需要的快照儲存下來;CodePro Profiler 還提供了快照的比較功能,不過前提是這兩個快照的型別必須相同(例如:都是以 sampling 模式或 BCI 模式執行的)。

[*]YourKit Java Profiler:當應用程式啟動後,使用者可以選擇在適當的時候進行快照獲取,針對記憶體快照,YourKit Java Profiler 還提供了自動獲取快照的功能;這些快照會被自動儲存到一個臨時的資料夾中,eclipse 關閉後,這些檔案不會消失;另外,YourKit Java Profiler 也提供了快照比較功能。

[*]JProfiler:工具會要求你指定一個目錄來儲存該 snapshot。
[/list]

[b]效能,在 sampling 模式下,這些工具的效能相差不大,這裡主要比較在 BCI 模式下的效能。[/b]

[list]
[*]TPTP:目前使用的 4.6.2 的版本沒有 BCI 模式。
[*]CodePro Profiler:當程式比較大的情況下,採用 BCI 模式進行 profiling 的速度比較慢;另外,在獲取記憶體洩露候選者的時候,速度也是相當慢。(當程式程式碼量 5 萬行時,用 CodePro Profiler 進行 Profiling 需要 5 分鐘,在獲取記憶體洩露候選者時,需要花費 20 分鐘)

[*]YourKit Java Profiler:BCI 模式下的執行速度還可以。(當程式程式碼量為 5 萬行時,需要 1 分鐘)
[*]JProfiler:感覺不出程式執行速度受影響。(當程式程式碼量為 5 萬行時,需要半分鐘)
[/list]


[b]健壯性[/b],
採用 CodePro Profiler 對比較大的應用程式進行 profiling 時,很容易出現棧溢位的錯誤。

[b]結論[/b]

TPTP 是一款基於 eclipse 的開源軟體,且提供的功能比較簡單,因此適用於基於 eclipse 開發的應用程式,且該應用程式比較簡單的情況;Codepro Profiler 提供的功能相對來說比較豐富,且與 eclipse 的整合性很好,但是在效能方面有待改善,因此適用於基於 eclipse 開發的應用程式,且對效能要求不高的情況;YourKit Java Profiler,JProfiler 與 Eclipse 的整合性都屬於一般,提供的功能也比較豐富,且效能不錯,因此適用於對 eclipse 整合度要求不高,且對效能要求較高的情況。