概述
誰實現Java應用程序的時候不出點問題?嗯,讓我們誠實一點吧...代碼分析器就是解決這個普遍問題的唯一的自定義工具。在本文中,Laurence Vanhelsuwé將為您回顧三種商用的Java分析器:Borland的Optimizeit Suite、 Quest Software的 JProbe Suite、以及ej-technologies的JProfiler。 現在的軟件是一個如此笨重的、如此多面性的家伙,以致沒有一個開發工具可讓程序員隨心所欲的完成他們的構想。甚至是運行--這個難以捉摸的尺度,當我們的代碼在二檔掙扎時恨得它要死;而當我們的代碼以一檔的速度運行時,我們卻愛得它要命--它包含了太多相關方面。
性能方面公認的問題有:主觀的用戶感知程序速度及響應速度。如果我們暫時排除用戶方面的因素,那麼評價運行速度就等於客觀實現方面的總和。這些方面有:算法選擇、整體內存的使用、對象的動態分配和釋放、以及多線程設計與運行行為。幫助你理解你的程序在運行時的維數選擇就是代碼分析器的繁重工作。
在本文中,我考慮了三種商用Java分析器並且判斷出哪一種分析器更容易滿足你我的需要:
· Borland的 Optimizeit Suite
· Quest Software的JProbe Suite
· ej-technologies的JProfiler
分析器原理
不必驚奇,這三種產品有許多共同點。所有現代分析器都是從同一個起點和約束開始的: Java 虛擬機分析器界面(JVMPI) (參考其他欄的 "The Java Virtual Machine Profiler Interface")。Sun微系統的API允許工具開發商接口或者連接到遵循JVMPI的JVM上,並且監控運作的方式以及JVM運行任何Java程序時的關鍵事件--從單獨的應用程序到 applet、servlet和企業JavaBeans (EJB)組件。
假定JVMPI強加給所有的分析器工具開發商一個標准的、同等的游戲場,那麼區分開發商高低的因素只在於工具的元特征(如,添加重要數值到原始JVMPI數據和功能上的特征,更為重要的是,繪圖用戶界面(GUI)應該針對這些特征進行開發),這也應該沒什麼稀奇的了。
在你看到該產品回顧的余下部分的時候,它的每一個自我形成或者自我突破的GUI都有自己的方法來解決如何開發原始的JVMPI 特征的核心問題,以便可以最大化分析和調試的效率。不幸的是,很多用到大型數據庫的應用程序都采用可視化的、直觀的真正友好的用戶界面,但沒有一個分析器能說服我:它們在這方面做得比較成功。
回顧的這三個分析器幾乎都有著同樣的分析會話期配置能力。所以在這我只是簡短的提一下,並且繼續進行比較:
· JVM 選擇
· 要分析的程序的選擇
· CLASSPATH 和資源路徑選擇
要啟動評價會話期,所有這三種產品都要求你選擇JVM,我們通常JVM上運行應用程序。一旦你選擇了JVM,你必須指定你的程序的主類,或者可執行的jar文件,如果你的程序要參數的話,也要指定哪種參數 。最後,為評價會話期設置CLASSPATH通常也要你指明你的源代碼層上的工具。圖1展示了一個典型的會話期配置對話框。
Figure 1.
在分析器內啟動一個程序意味著生成、捕捉、和觀察大量數據,所以所有的分析器都包含著不同的方法來控制數據的流動,在不同的標准以及每一封裝包的基礎上進行過濾。同樣也可以使用靈活的正規表達式類型模式如java.util.*或者jav*來完成。
三種產品的快速比較
在我探究具體的分析器特征(和非特征)之前,表格1 展示了每個產品關鍵點的屬性矩陣:
Table 1.屬性矩陣
Optimizeit Suite JProbe Suite JProfiler 版本 5.0 5.0 2.2.1 價格 $1,599 $2,0001 $499 免費評價 Yes Yes Yes 在線(安裝)幫助 Yes Yes (JavaHelp) Yes (JavaHelp)2 有無上下文相關幫助? Yes Yes Yes 安裝指南 Yes Yes No3 白皮書文件 No Yes No 工具模塊數 3 (Profiler, Thread Debugger,Code Coverage) 4 (Profiler, Coverage,Memory Debugger,Threadalyzer) 0 (all-in-one) 工具模塊是否單獨出售? No Yes No CPU 分析器 Yes (不實時) Yes (不實時) Yes (實時) 對象/堆棧 分析器 Yes Yes Yes 線程分析器 Yes Yes Yes 死鎖檢測 自動並可見 自動 手動 路徑條件檢測 No Yes No 代碼覆蓋 Yes Yes No 多JVM支持 Yes Yes Yes 深入到源代碼 Yes Yes Yes 深入到字節碼 No Yes Yes 遠程評價* Yes Yes Yes 自動評價** Yes Yes Yes IDE 集成 Yes Yes Yes 生成報告 Yes Yes Yes 主機平台許可政策 多平台和單一平台許可 單一平台許可 多平台 網址 http://www.borland.com/optimizeit/
index.html
http://www.jprobe.com/ http://www.jprofiler.com/ 易於使用度 7/10 4/10 8/10注釋:
* 遠程評價:在你的開發設備之外的其它設備上評價你的Java程序的執行
** 自動評價:實現無人看管的通宵的評價會話期;換句話說,不使用GUI驅動的命令列隊
1 JProbe Suite的價格包含一年的Gold Support (即技術支持)
2 ej-technologies的JProfiler的在線幫助幾乎不包含任何的視圖或者對話欄
3 ej-technologies'缺乏明確的指南將由某些演示會話期作出補償
測試平台
我驚喜地發現:從對宿主操作系統(OS)到對JAVA虛擬機的不同版本, 分析器對不同的平台都有廣泛的支持。實際上,大多數分析器支持每一個與商業相關的主機和/或JVM實現(這歸功於大量的排列,查看更多細節請浏覽開發商的產品網站)。一個例外就是Borland和 Quest Software的分析器都不支持Windows 98。據說是因為Windows 98 在實時精確度的處理方面不是一個"認真的"OS。(Windows 98通過它的公共API顯然只能提供50-ms嘀嗒信號的精確度, 毫無疑問,通過這樣一個粗糙的計時器的網絡許多方法將會以失敗告終)所以,在一個配置為900-MHz Athlon CPU、256 MB RAM 、運行Windows XP (Service Pack 1)的單獨的PC機上,我把這三個分析器都測試了一下。
為了方便組織這篇回顧,我將測試限制在單獨的Java 2平台、標准版(J2SE)應用程序內。 盡管這三種分析器明確表示支持servlet評價或者運行在不同應用服務上的EJB組件,他們的開發商也想借此盡力打進J2EE市場,但我還是沒有測試Java 2 Platform、 企業版(J2EE)應用程序。
你必須熟知應用程序的結構和實現,才能從使用分析器中獲得新知識,所以我主要依賴於我自己的兩個真實的作為評價試驗品使用的應用程序(見下面的表格2)。
Table 2. 配置的應用程序
程序名 World-on-a-Disc Slave 描述 用於CD/DVD-ROM的基於映射的多媒體引擎See http://www.worldonadisc.com/ 普通的可插文件和目錄處理器See www.lv2.clara.co.uk/slave.html 實現的"唯一致命弱點" CPU-bound I/O-bound 包含的類的數目 35 60+
所有這三個分析器都配送小型的演示應用程序。在使用這些工具評價程序之前,我覺得很有必要熟悉每個分析器,所以我干脆將它們的演示程序都玩了一遍。
Borland Optimizeit Suite
Borland的Optimizeit Suite是三者中最成熟,功能最齊全的分析器包。定價$1,599 , Borland無疑並不想占領獨立開發者市場。它的分析器由三個自由耦合的組件組成: Optimizeit Profiler、 Optimizeit Thread Debugger和Optimizeit Code Coverage。
Borland Optimizeit Suite的核心特征
Borland的Optimizeit分析器是用於CPU和堆棧/對象評價的組合工具包。圖2展示了一個典型的GUI屏幕快照。
Figure 2. Optimizeit Profiler的類實例圖:好看,但不中用。
圖2的類實例圖將現實中的對象分布制成表格,按類分組並且按照對象的多少進行排序。如果你之前沒有使用過堆棧分析器,請對此做好准備:不但在這個鏡頭中看到的你的程序低層實體可能完全讓你感到迷惑,而且一旦你迷惑了,你同樣看不到你的程序的源代碼。
Borland的分析器允許你點擊任何類並且看清分配了的該類的實例所在的位置。分析器不但告訴你存在分配的方法在哪裡(見圖3),而且只要你雙擊方法名,就會彈出一個分配語句行的源代碼閱讀器。
Figure 3. Optimizeit 分析器的對象分配回溯圖。
如果你的程序飽受分配熱點(即程序的某部分分配了太多的對象)之苦,或者你想追蹤你程序中不應該出現的真實對象的來源(如XML解析器中的抽象窗口工具包(AWT)的有顏色的對象,或者混亂出現在只應該出現命令行的實體中的Swing 對象),那麼上述特征就非常非常有用了。
存儲檢漏儀(Memory Leak Detector)允許你比較你的程序的堆棧的兩種瞬象,從而有希望找出被引用的對象中有多少就要斷裂的被遺漏的對象。注意,盡管這個工具稱做存儲檢漏儀,而且它也大大的削減了大海撈針的范圍,但檢測存儲漏洞仍然是一件艱巨的手工勞動。
分析器的實例演示(Instance Display)也揭示存儲漏洞。 這個工具可讓你深入到對象圖表的極度精微的程序。你可以分析你的應用程序中的任何一個真實對象的進出索引。我對這個實例演示的疑問就是: Borland沒有為了工具的這個部分而使用傳統的可視化圖表;相反,這個工具使用的是表格和樹的綜合,如圖4所示。
Figure 4. Optimizeit 分析器的對象實例視圖。
線程調試器被放在Borland的分析器的第二個模塊內。它由所有真實線程以及它們狀態(運行,等待,調度,在本機輸入/輸出(I/O)設備上的阻塞)的實時顯示,再加上幾種其它的可幫助你分析死鎖和資源瓶頸的視圖組成。在實時的視圖中,每個線程行告訴你對象鎖定多少--程序稱作"監控器"--線程有多少以及該線程鎖住多久了。圖5舉例說明了一個典型的線程調試會話期。
Figure 5. 線程調試器的默認視圖顯示實時線程活動和狀態。
如果你曾經花過一段時間調試線程問題的話,你肯定會同意下列特征使得線程調試器非常有價值:直接死鎖檢測和可視化(見圖6)、線程爭用、線程等待、和附加嵌套的鎖定分析。
Figure 6.線程調試器包含檢測和顯示死鎖的邏輯。
Borland 的三件套中的第三個模塊Code Coverage,作了一件相當好的工作,它向你展示 所有你系統的線程所觀察到的程序部分。這個綜合圖將類按百分比列出,點擊任何類都會彈出執行行用黃色顯示的源代碼視圖。
Borland Optimizeit Suite的缺陷
Borland的三件套結構還不如一個結構,因為它只是一個將三個完全不同的程序放在一起的缺乏彈性的皮帶。這就是說,如果你正在使用分析器,接下來又想使用線程調試器做一些線程分析,那你就要切換程序並啟動一個全新的會話期。這就不是我們所說的模塊組集成了。
線程調試器確實可以使用過濾器特征,它可讓你調整你必須費力完成的數據的數量。目前,你不得不觀察所有的真實的線程(從任何線程組信息中剝離出來的),就像觀察顏色編碼的彩虹帶卷動的傳送帶一樣:漂亮,但要將信號從噪音中分離出來並不是一件十分容易的事情。 反映Java線程組層級的分層觀察特征也不會出現什麼差錯。另外,時間表示的格式也可以改進:不打印Thread-2 waited 23507561 ms,改為Thread-2 waited 6 h:31 m:47.561 s 可能更會受到程序員的歡迎。
Optimizeit只要用字節顯示對象,它就會使用124b的格式。像我這樣一個已經灌了一些東西到許多的十六進制垃圾桶的老黑客,這種格式總是觸發十六進制的 "B" déjà vu。我的大腦已經大大地將同樣的信息格式化成124字節。
Code Coverage的源代碼顯示也是有一點花架子:它只是用黃色使得執行的代碼行突出,而剩下的均為白色(即不突出顯示)。這種方法看起來當然不錯,但如果它也認為緊挨被執行的代碼之後的白色部分(包括注釋)也同樣的被執行,那這個特征將會有用的多。結果可能要好看得多得多,在顯示的間隙還可以顯示線程沒有涉及的代碼。
Quest Software的 JProbe Suite
Quest Software的JProbe Suite 在功能和價格上與Borland的Optimizeit Suite差不多。它也提供獨立的工具模塊來解決評價問題,模塊有四: JProbe Profiler、JProbe Coverage、JProbe Memory Debugger、和JProbe Threadalyzer。
與其他兩個分析其發行商不同,Quest Software單獨發售個別模塊組件;如JProbe Profiler一個就要$849 (包括一年的技術支持)。
JProbe Suite的關鍵特征
JProbe的評價方法集中在JVM實現數據瞬象的概念上。你可以為了以後的重新裝載和後續的分析保存瞬象,並且比較兩種瞬象以找出差別。圖7 顯示了一個典型的JProbe Profiler窗口,它包含兩個用於分析的瞬象。
Figure 7. 一個典型的高級JProbe GUI顯示用於(靜態)分析的評價瞬象。
敲擊一下,中心瞬象方法表示多數JProbe分析已經離線,不再是實時的了。這種方法對於堆棧分析很有意義,但是對於CPU實現評價就過於嚴格了。
對於CPU評價的所有重要的任務來說,JProbe要麼提供表格式視圖(如圖8),要麼提供圖表式視圖(如圖9)。它沒有提供讓你深入到調用堆棧分支的直覺的Swing JTree類型的視圖。
Figure 8. 一個典型的JProbe Profiler表格顯示收集的實時方法。
Figure 9. 用圖表顯示的JProbe 實時方法。
JProbe的第二個模塊,Memory Debugger允許你使用多種方式對堆棧瞬象進行操作。 它也包含一個簡單而有效的使用實例分析的功能,它允許你在啟動使用實例之前重新設置收集的數據。Memory Debugger也允許你定義任何實例數的計算限度(Quest Software有點模糊地稱之為"斷言"),在使用實例結束的時候,如果類生成的對象超過了你的期望值這個計算限度就會提醒你。圖10顯示了JProbe的堆棧概要圖。
Figure 10. JProbe的堆棧概要圖是Memory Debugger模塊的主視圖。
Memory Debugger的實例細節圖(圖11)讓你可以分析出哪個對象涉及到了焦點對象以及焦點對象涉及到了哪個對象。
Figure 11.
引用圖表視圖(圖12)允許你以一種輝煌但經常無法抵抗的圖表細節來分析流入和流出的引用。
Figure 12.
如果纏在一起的意大利面條對你來說聽起來就好比聽二十世紀七十年代的減速火箭的話, Memory Leak Doctor顯示的對象引用鏈有產生存儲遺漏的潛在可能(圖13)。Leak Doctor 可讓你在一個堆棧瞬象上實現"如果我刪除一個引用會怎樣"的試驗,並且看看這種操作能否解決你的存儲遺漏問題。
Figure 13.
Memory Debugger的又一個有用的性能是Garbage Monitor;它可以追蹤用於暫時存在的對象如幕後的對象StringBuffer之類的分配熱點。這種對象可使用語法級的字符串進行串聯(與API級別的串聯相反)。
JProbe的 Threadalyzer是JProbe Suite的線程分析模塊,並有著足以自豪的、可以自動檢測問題的許多有用的性能。這些問題有:
· 死鎖(現有的和潛在的)
· 線程遲延
· 數據競爭
但是,解決這些以外的其他方面的性能,GUI就遠遠沒有那麼直觀了。
JProbe Suite的活頁(紙)文件的編寫和設計(在布局、屏幕快照的使用、和圖標方面)應該說做得相當好。而且更進一步的是,它還告訴讀者一些有價值的技術性能分析的方法和技巧,並且就如何將分析集成到你的軟件開發方法中去提出一些基本的建議。
JProbe Suite的缺陷
盡管JProbe在工具市場占的份額高,我對於它的粗糙和不成熟仍然感到失望。它看起來感覺就像一個存在了多年但是卻沒有從偶爾的信手重新設計這種增長需求中獲益的軟件。因此JProbe Suite 5.0則在經典的"特征化"的重壓下呻吟。我發現JProbe只有極少數方面才真正直觀或者功能相當強大。學會使用JProbe是一件真正困難的任務。Memory Debugger中從左邊、右邊和中間彈出的GUI很不直觀,尤其讓人感到迷惑,而且我在許多的地方徹底迷惑了。
其它的JProbe 問題有(無固定順序):
· 難於解釋和交互的圖形顯示(圖形和方法定時)
· 由混亂的十六進制數識別對象,而不是由它們的更為啟發性的toString()表示法識別。
· 工具欄圖標對於我的二十英寸、1280 x 1024 像素的屏幕來說實在是太小了。
· 方法適時表格只顯示文字數字的數據信息,而不是文本、圖表和顏色的綜合信息。
· 在下列三種模塊的表格中使用了三種不同的外觀:Code Coverage、 Garbage Monitor和 Profiler。
· 好像標准的Swing組件沒有用在表格中,導致了沒有一個標准的外觀。
· 太多不同的窗口/視圖很少表現出整體的連貫性或者主要構思。
· 在線幫助有時遞交的是被破壞的文本(可能在JProbe使用的JavaHelp中出現故障)。
· 數不清的窗口通過一大串按鈕點擊來連接,但是卻沒有返回/前進機制。
· 報告打印可以刪掉:PDF產生之後發送到Acrobat Reader(安裝一下就可以了)。我的測試設備上已經有了一個Acrobat 4.0 ,但是Acrobat 與報告打印模式不兼容:"文件打開出現錯誤。文件不存在"。
· 在Code Coverage模式中,Generate Report對話框打開時竟然比我的1024行的桌面還要高(OK 和Cancel 按鈕完全不在屏幕上了!)
ej-technologies的 JProfiler
如果你以前沒聽說過ej-technologies公司,那也沒什麼好驚奇:作為一個2001年才成立的德國公司,ej-technologies公司在Java工具市場確實是後起之輩。它在2002年2月發行JProfiler 1.0版本,並在2003年4月發行它的2.2.1版本(本文提到過)。(它同時也生產開放式源代碼Java類庫類文件API 和類閱讀器。JProfiler使用這類閱讀器 )ej-technologies公司的誕生和旗艦產品的問世代表著JProfiler的設計已經從巨大數量的後見之明中獲益:它的GUI比Quest Software公司的JProbe Suite要容易操作的多。
JProfiler的核心性能
JProfiler 與前面兩個分析器差別甚大,因為它采用了可以檢測不同分析尺度的統一工具: 他只由一個工具組成。這個工具只是使用了四種不同的視圖設置,可讓你從不同角度分析你的程序,而且不必重啟會話期或者切換到不同的程序。比起那些工具片斷組合來說,這個方法的簡單性和對稱性要討人喜歡,要有意義的多。而且在那些工具中,用戶接口相互不連貫,功能判斷也比較武斷,這些缺點把工具的優勢全破壞掉了。
四種JProfiler 視圖設置是:
1. 存儲視圖(堆棧和對象圖表分析)
2. CPU 視圖(方法適時性)
3. 線程視圖
4. VM 遙測視圖
這些視圖可以細分到形成產品中心的子視圖。圖14顯示的Profiler有自己的關鍵Views下拉菜單。
Figure 14.
盡管Views菜單清楚地反映出產品的整體結構,視圖之間的快速切換只需要在左邊的垂直工具欄中點擊就可以了,然後在窗口按鈕的跳格鍵中隨意地選擇一個指定的類型。
方法計時可用作方法調用樹,它可以顯示時間消耗和絕對時間消耗的百分比。圖15顯示的正是這種樹。
Figure 15. JProfiler的調用樹視圖(三個CPU視圖中的一個)。
JProfiler允許你左擊與調用樹的每一行關聯的上下文菜單 ,從而深入到消耗周期方法的源代碼或者字節碼。單個線程或者線程組可過濾方法評價的信息。JProfiler 也有一個子視圖,它可列出由JVM識別的代碼熱點,這些代碼已經編譯成本地代碼。
幾種存儲視圖支持堆棧分析。圖16顯示的監控器子視圖與Borland 的類似。
Figure 16. JProfiler的類監控器視圖(四個存儲視圖中的一個)。
將高端技術指標集成到一個易於操作的GUI上,這是一件了不起的事情,但JProfiler的Heap Walker 模塊(圖17)卻是它的唯一敗筆。它的六個子視圖的子視圖更象一個程序內部的程序,它應該集中解決它的有效使用問題,而不是擴展產品的其它性能。
Figure 17. JProfiler's Heap Walker 主頁圖。
線程視圖設置的五個子視圖集中處理:線程的過去狀態和當前狀態(運行、等待、和阻塞)、監控器的過去使用和當前使用、以及監控器的統計表。這些視圖比直接觀察原始數據要好一點。但是這些視圖中沒有一個可以自動的智能的幫助你識別競爭條件、死鎖、或者線程的其他噩夢。圖18顯示的是一個典型的線程視圖。
Figure 18.
VM 遙測視圖設置的五個不同的實時滾動曲線圖顯示:堆棧空間的使用情況和空閒情況、對象數(有助於分出排列和非排列兩類)、已經裝載的類數、垃圾收集器的活動、和線程數。圖19 顯示了這種視圖設置。
Figure 19.
JProfiler的缺陷
JProfiler的 CPU 分析器中缺少的一個簡單特征就是Reset或者Clear Data命令。 例如,當你分析一個Swing應用時,應用程序裝載和初始化過程中收集的數據,與激活應用程序某個特征時收集的數據,這兩種性能數據有著本質的差別。但是,一旦裝載了測試應用程序,我就會清除紀錄,以便集中處理具體的使用案例。目前, JProfiler不支持這種基本分析模式。
JProfiler的在線幫助過於簡單,它缺乏實例、詳細的指南以及GUI屏幕快照。盡管JProfiler 是這三個分析器中最直觀地分析器,但是缺乏足夠的在線幫助使得它的Heap Walker 模塊更難理解。
結束語
盡管不用分析器對你的應用程序進行評價也有可能編寫出穩定的Java應用程序,但你也知道啃下這塊硬骨頭將帶給你許多許多麻煩。任何連續運轉幾天或者幾個星期(甚至幾個月)不間斷的應用程序必須確認是穩定的。為了這個,你必須十分徹底地逐條測試你系統的內部運行行為。
所有這三個分析器都能處理我的兩個實驗應用程序。在我的900-MHz的設備上,分析器的評價活動減慢了應用程序的速度,但是分析器分析或者調試任務的活動卻沒有。
在這三個分析器中,我喜歡Borland的 Optimizeit Suite和ej-technologies的JProfile,當然它們還是有潛力改進的。ej-technologies的JProfiler的價格還是很有競爭力的,它對於小規模的公司的吸引力很大,但是大一點的公司毫無疑問會青睐 Borland的 Optimizeit Suite ,因為它的功能設置要豐富一些。如果你為你的團隊挑中Optimizeit,注意Borland的 JBuilder 8.0和9.0 (企業版)已經包含了集成到JBuilder IDE 上的Optimizeit Suite 5.0。
最後,我不得不承認,為了推薦Quest Software的JProbe Suite,我的頭都大了。評價現實生活中的Java系統是一件高技巧、高技能、和費時的工作,而且你最不想見到的一件事就是:分析器使得你的工作更加困難,你會發現它不但沒有簡化你的工作,而是把它弄得更加復雜。JProbe Suite 的許多性能需要改造的地方就是改進GUI的設計,使得它具有整體連貫性,因為現在的它分析代碼時太不連貫了,讓人老是感覺灰心,簡直是無法忍受了。