JDK中還藏著一個寶貝 它的名字叫做VisualVM
原創【51CTO獨家譯稿】令人意想不到的寶貝,其實往往已經早就在你眼前,只不過你沒發現它。VisualVM就是這樣的。每當我們升級JDK、打開IDE時,其實我們就用上了它所帶來的新特性。至少,我自己是這樣認為的。
我第一次獲知VisualVM是在去年二月份Geertjan Wielenga所寫的一篇文章里,那時它的第三版都已經發布了。可以說VisualVM是Java開發者最為重要的工具,但同時這也是最不為人知的秘密。在Java的運行效率仍然是個問題的情況下,正是它有效的解決了這個問題。(有關VisualVM的簡介,可參考51CTO之前發布的Sun VisualVM項目 開源Java問題解決方案一文)
VisualVM簡介
簡單說來,VisualVM是一種集成了多個JDK命令行工具的可視化工具,它能為您提供強大的分析能力。所有這些都是免費的!它囊括的命令行工具包括jstat, JConsole, jstack, jmap 和 jinfo,這些工具與JDK的標準版本是一致的。
你可以使用VisualVM生成和分析海量數據、跟蹤內存泄漏、監控垃圾回收器、執行內存和CPU分析,同時它還支持在MBeans上進行瀏覽和操作。盡管VisualVM自身要在JDK6這個版本上運行,但是JDK1.4以上版本的程序它都能監控。
對于我來說,這些功能都是至關重要的。以前我一直在使用如YourKit這樣的一些付費軟件來檢測我的應用軟件,但現在我可以用VisualVM這樣一個開源工具來實現同樣的功能。更何況,有誰比能Sun公司更了解JVM呢?
如何獲取VisualVM
VisualVM的一個最大好處就是,它已經在你的JDK bin目錄里了,只要你使用的是JDK1.6 Update7之后的版本。點擊一下jvisualvm.exe圖標它就可以運行了。
你所需要做的只是點一下jvisualvm.exe,就能啟動它。運行中的所有Java應用程序將顯示在右邊的導航欄。你會發現根本不需要在VisualVM 里親自為你的應用程序注冊,因為它們全都會自動顯示出來。你甚至還可以在導航欄里查看到遠程的應用程序。
顯示為“未知進程”(pid為5392)的程序是Eclipse
使用VisualVM
VisualVM有很多令人眼前一亮的功能,它能使你:
◆監控應用程序的性能和內存占用情況
◆監控應用程序的線程
◆分析(Profile)應用程序性能和內存分配情況
◆進行線程轉儲(Thread Dump)或堆轉儲(Heap Dump)
◆分析核心轉儲(Core Dump)
◆保存快照以便脫機分析應用程序。
用VisualVM評估IDE
我很想用VisualVM 做點什么,于是我決定,用它來對目前最先進的三個IDE進行評測。為此我特意新安裝了 NetBeans 6.5.1 (JavaSE only version) , Eclipse (for Java Developers) 和 IntelliJ IDEA (8.1.2).
測試如下:
◆在VisualVM 中運行內存分析器(Memory Profiler)
◆在IDE中創建一個新的項目
◆創建一個簡單的類,這個類只有一個可以打印“Hello World"的main方法
◆保存內存分析結果
◆生成這個應用程序的堆轉儲(Heap Dump)
◆從VisualVM 的監視視圖(Monitor View)里獲取信息
◆重新啟動IDE,使用CPU分析器(CPU Profiler),在IDE中執行相同的步驟
◆保存CPU分析器(CPU Profiler)的結果
我意識到,CPU和內存評測其實是可以同時進行的,但為了便于下文的解釋,我特意將它們分別進行。
我用IntelliJ做測試時,發現只有用我自己的JDK才能啟動它,而不能用它自帶的。雖然我太不熟悉這個IDE,但我發現當我用JSDK創建新工程時,它必須解析JDK中的文件。
此外,請注意,這些IDE都是我剛剛才下載的默認版本,沒有針對Java開發作什么優化處理。
#p#
堆轉儲
我發現要對軟件進行全面對比時,最好的手段是進行堆轉儲(Heap Dump)。這在程序運行時,使用VisualVM可以讓這項工作變得十分太簡單,你隨時都可以右鍵單擊那個程序,然后選擇 Heap Dump 就可以了。
在個領域我評測的兩個指標是:字節總數和類(class)的總數
NetBeans:
◆總的字節數:31,576,772
◆總的類數:10,583
IntelliJ :
◆總的字節數:76,582,715
◆總的類數:14,368
Eclipse:
◆總的字節數:62,112,960
◆總的類數:11,428
很明顯,NetBeans只用到了Eclipse的一半都不到,IntelliJ則用去了多得多。
而在監視視圖(Monitor View)里看著這些程序運行特別有意思,在這里我只關注了線程中的本地類,Eclipse差不多達到了25K,IntelliJ大概27K,NetBeans則在20K以下。
#p#
內存和CPU評測(Profile)結果
我注意到,當我開始評測(profiling)時,類和方法中的指令執行總是要讓我等上好一段時間。尤其是在IDE里,這段時間不算短,不過還算可以接受吧。
內存和CPU評測對這些IDE的意義不是很大。但進行這個分析所帶來的一個方便之處就是:你很容易就可以找到程序哪個地方發生了內存泄漏。以下是對這幾個IDE的評測結果。
在這些IDE的評測結果中,我們可以看到一些很有趣的幾點。例如,NetBeans中用到了大量了byte[] ,而在Eclipse和IntelliJ中就明顯少得多了。另外我們還可以看到char[]在所有IDE里均被大量使用了。
◆NetBeans:內存的19.6%
◆Eclipse:內存的31.6%
◆IntelliJ:內存的32.7%
通過CPU評測我們能看出程序的哪個地方耗時最多。在這方面,各個IDE分別把時間用在了不同的方法(method)上,這一點有很大的不同:
◆NetBeans大部分時間花費在org.openide.util.RequestProcessor $ Processor.run()- 58.1 %
◆Eclipse的時間花在java.lang.reflect.Method.invoke()- 約占45.5 %
◆IntelliJ在java.net.SocketInputStream.read()上耗費掉了38.7 %的時間
雖然這么一個橫向對比不一定能夠說明什么問題。但能夠看到這些IDE在幕后不同的工作方式,也是一件很有趣的事情。
至此,我不得不認為VisualVM 讓這項評測變得相當的簡單。我只需要在這些IDE啟動之前運行VisualVM,它就能自動發現并掛載隨后啟動的每個IDE實例,然后就可以在VisualVM里作評測了。
#p#
IDE集成
Java開發人員大多都是被IDE慣壞了的,一旦沒有順手的IDE可用就會無所適從。不過不用擔心,當前流行的這些IDE都已經有了VisualVM插件,這樣你就可以在你最喜歡的IDE里工作了,不用再跟命令行打交道了。
VisualVM在NetBeans里的集成很有意思,它其實已經是NetBeans默認的分析器了。在NetBeans中,它作為一個RCP程序,可以與其它的NetBeans模塊一起進行更好地擴展。
Eclipse和 IntelliJ IDEA的集成包可以通過點擊這里獲取。MyEclipse 7.5也已經集成了VisualVM的插件。作為一個Eclipse開發者,我很感興趣這是究竟怎么辦到的,因為這個工具畢竟是在NetBeans平臺基礎之上構建的。
與Eclipse的集成
首先,你得下載VisualVM Launcher插件,將它解壓到你的Eclipse主目錄里。這樣當你打開Run Configurations對話框時,就會看到程序啟動器選項。默認的啟動器是可以在偏好(Preferences)設置里修改的。
在我的設置里,我選擇當使用啟動器時讓VisualVM Launcher運行,其它時候就使用Eclipse默認的程序Launcher。你可以針對你的應用、小程序或者是Eclipse項目修改這些設置。
然后你還得指定你所要采用的VisualVM 可執行文件和JDK的路徑。
這樣與Eclipse的集成就算完成了,它會自動啟動一個VisualVM ,你就可以用了。以后可能會有更深度的集成 ,那樣的話說不定我就直接可以在IDE里啟用它去分析程序了。
擴展VisualVM
如果上面列舉的這些功能還不能滿足你的需要,那么你還可以編寫自己的VisualVM插件。VisualVM提供了許多的API調用入口,如下圖所示:
◆標簽擴展(Tab extension)。默認情況下,VisualVM提供了像“Overview",Monitor,Threads這樣的一些標簽。你可以自己定制一些類似的標簽。此外,這些標簽自身也可以擴展,你可以為它們設置二級標簽,還可以設置這些標簽是對所有VisualVM數據源都可見,還是只針對一些特定的數據源類型。
◆二級標簽擴展(Subtab extension)。在上面所說的這些標簽里,你可以插入新的標簽,當然,這是在標簽被設置為可擴展的前提下。可擴展的標簽有:"Overview"、"Monitor"、"Threads"、"Heap Dump"和"Host"。當你插入一個新的子標簽時,你可以指定它與其它子標簽的相對位置關系。子標簽也可以設置是對所有VisualVM數據源都可見,還是只針對一些特定的數據源類型。
◆菜單擴展(Menu extension)。一個數據源以及它的子節點,都可以為它們的上下文菜單添加一個或若干個菜單。
◆應用類型擴展(Application type extension)。在默認情況下,除非提供了一個特定的插件,否則在VisualVM里可見的這些應用都是一樣的,它們有著同樣的圖標和標簽。在定義了一種應用類型之后,你可以為這種特定的應用再安裝一個插件,這樣做可以為不同的應用具有不同的圖標(比較簡單),也可以提供像繪圖這樣的額外功能。
◆數據源的擴展(Data source extension)。 “應用程序”的數據源只是VisualVM可以監管的一種數據源類型。另一種數據源類型是“主機”數據源,它可讓你監控和管理本地的和遠程的主機。如果VisualVM的默認配置不能滿足你的需求,你可以創建新的數據源類型讓它監管。
在VisualVM的官方網站上,有一個關于編寫VisualVM插件的詳細說明,這份說明淺顯易懂,如果你以前有過在NetBeans或者Eclipse上有過開發插件的經歷,那就更容易上手了。不僅如此,VisualVM的插件中心里已經有不少現成的插件可用,只需進入“工具”/“插件”就可以看到了。
VisualVM 簡單易用(相信你已經會用它了),還具備可供擴展的平臺,這些都必將使它成為開發者不可或缺的工具。讓我印象非常深刻的是,它能夠自動掛載運行中的程序,而不用開發者去做注冊工作。在理論上,我們甚至還可以在完善和再次啟動Java應用程序的時,讓它一直在后臺運行,這實在是太妙了。
JDK中還藏著一個寶貝,它的名字叫做VisualVM。趕快去下載運行,讓它幫你找出程序中的所有不足吧。
【編輯推薦】