天天看點

jdk 調優 VisualVM

visualvm在 jdk安裝目錄的bin目錄下,可直接輕按兩下使用

開發大型 java 應用程式的過程中難免遇到記憶體洩露、性能瓶頸等問題,比如檔案、網絡、資料庫的連接配接未釋放,未優化的算法等。随着應用程式的持續運作,可能會造成整個系統運作效率下降,嚴重的則會造成系統崩潰。為了找出程式中隐藏的這些問題,在項目開發後期往往會使用性能分析工具來對應用程式的性能進行分析和優化。

visualvm 是一款免費的性能分析工具。它通過 jvmstat、jmx、sa(serviceability agent)以及 attach api 等多種方式從程式運作時獲得實時資料,進而進行動态的性能分析。同時,它能自動選擇更快更輕量級的技術盡量減少性能分析對應用程式造成的影響,提高性能分析的精度。

本文将對 visualvm 的主要功能逐一介紹并探讨如何利用獲得的資料進行性能分析及調優。

<a target="_blank" href="http://www.ibm.com/developerworks/cn/java/j-lo-visualvm/#ibm-pcon">回頁首</a>

監視:監視是一種用來檢視應用程式運作時行為的一般方法。通常會有多個視圖(view)分别實時地顯示 cpu 使用情況、記憶體使用情況、線程狀态以及其他一些有用的資訊,以便使用者能很快地發現問題的關鍵所在。

轉儲:性能分析工具從記憶體中獲得目前狀态資料并存儲到檔案用于靜态的性能分析。java 程式是通過在啟動 java 程式時添加适當的條件參數來觸發轉儲操作的。它包括以下三種:

系統轉儲:jvm 生成的本地系統的轉儲,又稱作核心轉儲。一般的,系統轉儲資料量大,需要平台相關的工具去分析,如 windows 上的 windbg 和 linux 上的 gdb。

java 轉儲:jvm 内部生成的格式化後的資料,包括線程資訊,類的加載資訊以及堆的統計資料。通常也用于檢測死鎖。

堆轉儲:jvm 将所有對象的堆内容存儲到檔案。

快照:應用程式啟動後,性能分析工具開始收集各種運作時資料,其中一些資料直接顯示在監視視圖中,而另外大部分資料被儲存在内部,直到使用者要求擷取快照,基于這些儲存的資料的統計資訊才被顯示出來。快照包含了應用程式在一段時間内的執行資訊,通常有 cpu 快照和記憶體快照兩種類型。

cpu 快照:主要包含了應用程式中函數的調用關系及運作時間,這些資訊通常可以在 cpu 快照視圖中進行檢視。

記憶體快照:主要包含了記憶體的配置設定和使用情況、載入的所有類、存在的對象資訊及對象間的引用關系等。這些資訊通常可以在記憶體快照視圖中進行檢視。

性能分析:性能分析是通過收集程式運作時的執行資料來幫助開發人員定位程式需要被優化的部分,進而提高程式的運作速度或是記憶體使用效率,主要有以下三個方面:

cpu 性能分析:cpu 性能分析的主要目的是統計函數的調用情況及執行時間,或者更簡單的情況就是統計應用程式的 cpu 使用情況。通常有 cpu 監視和 cpu 快照兩種方式來顯示 cpu 性能分析結果。

記憶體性能分析:記憶體性能分析的主要目的是通過統計記憶體使用情況檢測可能存在的記憶體洩露問題及确定優化記憶體使用的方向。通常有記憶體監視和記憶體快照兩種方式來顯示記憶體性能分析結果。

線程性能分析:線程性能分析主要用于在多線程應用程式中确定記憶體的問題所在。一般包括線程的狀态變化情況,死鎖情況和某個線程線上程生命期内狀态的分布情況等

visualvm 是一個性能分析工具,自從 jdk 6 update 7 以後已經作為 oracle jdk 的一部分,位于 jdk 根目錄的 bin 檔案夾下。visualvm 自身要在 jdk6 以上的版本上運作,但是它能夠監控 jdk1.4 以上版本的應用程式。下面主要介紹如何安裝 visualvm 以及各種 visualvm 上的插件。

visualvm 項目的官方網站目前提供英文版本和多語言支援版本下載下傳。多語言版本主要支援英語、日語以及中文三種語言。如果下載下傳安裝多語言版本的 visualvm,安裝程式會依據作業系統的目前語言環境去安裝相應 visualvm 的語言版本。最新 visualvm 版本主要支援的作業系統包括:microsoft windows (7, vista, xp, server)、linux、sun solaris、mac os x、hp-ux 11i。本文以 microsoft windows xp 為安裝環境并支援中文。

visualvm 安裝程式。

将 visualvm 安裝程式解壓縮到本地系統。

導航至 visualvm 安裝目錄的 bin 目錄,然後啟動 jvisualvm.exe。

(.nbm 檔案 ) 安裝第三方插件為 visualvm 添加功能。

從 visualvm 插件中心安裝插件安裝步驟 :

從主菜單中選擇“工具”&gt;“插件”。

在“可用插件”标簽中,選中該插件的“安裝”複選框。單擊“安裝”。

逐漸完成插件安裝程式。

jdk 調優 VisualVM

根據 .nbm 檔案安裝第三方插件安裝步驟 :

在“已下載下傳”标簽中,點選"添加插件"按鈕,選擇已下載下傳的插件分發檔案 (.nbm) 并打開。

選中打開的插件分發檔案,并單擊"安裝"按鈕,逐漸完成插件安裝程式。

jdk 調優 VisualVM

下面我們将介紹性能分析的幾種常見方式以及如何使用 visualvm 性能分析工具進行分析。

visualvm 通過檢測 jvm 中加載的類和對象資訊等幫助我們分析記憶體使用情況,我們可以通過 visualvm 的監視标簽和 profiler 标簽對應用程式進行記憶體分析。

在監視标簽内,我們可以看到實時的應用程式記憶體堆以及永久保留區域的使用情況。

jdk 調優 VisualVM
jdk 調優 VisualVM

此外,我們也可以通過 applications 視窗右擊應用程式節點來啟用“在出現 oome 時生成堆 dump”功能,當應用程式出現 outofmemory 例外時,visualvm 将自動生成一個堆轉儲。

jdk 調優 VisualVM

在 profiler 标簽,點選“記憶體”按鈕将啟動一個記憶體分析會話,等 visualvm 收集和統計完相關性能資料資訊,将會顯示在性能分析結果。通過記憶體性能分析結果,我們可以檢視哪些對象占用了較多的記憶體,存活的時間比較長等,以便做進一步的優化。

此外,我們可以通過性能分析結果下方的類名過濾器對分析結果進行過濾。

jdk 調優 VisualVM

visualvm 能夠監控應用程式在一段時間的 cpu 的使用情況,顯示 cpu 的使用率、方法的執行效率和頻率等相關資料幫助我們發現應用程式的性能瓶頸。我們可以通過 visualvm 的監視标簽和 profiler 标簽對應用程式進行 cpu 性能分析。

在監視标簽内,我們可以檢視 cpu 的使用率以及垃圾回收活動對性能的影響。過高的 cpu 使用率可能是由于我們的項目中存在低效的代碼,可以通過 profiler 标簽的 cpu 性能分析功能進行詳細的分析。如果垃圾回收活動過于頻繁,占用了較高的 cpu 資源,可能是由記憶體不足或者是新生代和舊生代配置設定不合理導緻的等。

jdk 調優 VisualVM

在 profiler 标簽,點選“cpu”按鈕啟動一個 cpu 性能分析會話 ,visualvm 會檢測應用程式所有的被調用的方法。當進入一個方法時,線程會發出一個“method entry”的事件,當退出方法時同樣會發出一個“method exit”的事件,這些事件都包含了時間戳。然後 visualvm 會把每個被調用方法的總的執行時間和調用的次數按照運作時長展示出來。

此外,我們也可以通過性能分析結果下方的方法名過濾器對分析結果進行過濾。

jdk 調優 VisualVM

java 語言能夠很好的實作多線程應用程式。當我們對一個多線程應用程式進行調試或者開發後期做性能調優的時候,往往需要了解目前程式中所有線程的運作狀态,是否有死鎖、熱鎖等情況的發生,進而分析系統可能存在的問題。

在 visualvm 的監視标簽内,我們可以檢視目前應用程式中所有活動線程和守護線程的數量等實時資訊。

jdk 調優 VisualVM

visualvm 的線程标簽提供了三種視圖,預設會以時間線的方式展現。另外兩種視圖分别是表視圖和詳細資訊視圖。

時間線視圖上方的工具欄提供了縮小,放大和自适應三個按鈕,以及一個下拉框,我們可以選擇将所有線程、活動線程或者完成的線程顯示在視圖中。

jdk 調優 VisualVM
jdk 調優 VisualVM

我們在詳細資訊視圖中不但可以檢視所有線程、活動線程和結束的線程的詳細資料,而且也可以檢視某個線程的詳細情況。

jdk 調優 VisualVM

我們可以使用 visualvm 的快照功能生成任意個性能分析快照并儲存到本地來輔助我們進行性能分析。快照為捕獲應用程式性能分析資料提供了一個很便捷的方式因為快照一旦生成可以在任何時候離線打開和檢視,也可以互相傳閱。

visualvm 提供了兩種類型的快照:

profiler 快照:當有一個性能分析會話(記憶體或者 cpu)正在進行時,我們可以通過性能分析結果工具欄的“快照”按鈕生成 profiler 快照捕獲當時的性能分析資料。

jdk 調優 VisualVM

應用程式快照:我們可以右鍵點選左側 applications 視窗中應用程式節點,選擇“應用程式快照”為生成一個應用程式快照。應用程式快照會收集某一時刻的堆轉儲,線程轉儲和 profiler 快照,同時也會捕獲 jvm 的一些基本資訊。

jdk 調優 VisualVM

visualvm 能夠對正在運作的本地應用程式生成線程轉儲,把活動線程的堆棧蹤迹列印出來,幫助我們有效了解線程運作的情況,診斷死鎖、應用程式癱瘓等問題。

jdk 調優 VisualVM

當 visualvm 統計完應用程式内線程的相關資料,會把這些資訊顯示新的線程轉儲标簽。

jdk 調優 VisualVM

visualvm 能夠生成堆轉儲,統計某一特定時刻 jvm 中的對象資訊,幫助我們分析對象的引用關系、是否有記憶體洩漏情況的發生等。

jdk 調優 VisualVM

當 visualvm 統計完堆内對象資料後,會把堆轉儲資訊顯示在新的堆轉儲标簽内,我們可以看到摘要、類、執行個體數等資訊以及通過 oql 控制台執行查詢語句功能。

堆轉儲的摘要包括轉儲的檔案大小、路徑等基本資訊,運作的系統環境資訊,也可以顯示所有的線程資訊。

jdk 調優 VisualVM

從類視圖可以獲得各個類的執行個體數和占用堆大小數,分析出記憶體空間的使用情況,找出記憶體的瓶頸,避免記憶體的過度使用。

jdk 調優 VisualVM

通過執行個體數視圖可以獲得每個執行個體内部各成員變量的值以及該執行個體被引用的位置。首先需要在類視圖選擇需要檢視執行個體的類。

jdk 調優 VisualVM
jdk 調優 VisualVM

此外,還能對兩個堆轉儲檔案進行比較。通過比較我們能夠分析出兩個時間點哪些對象被大量建立或銷毀。

jdk 調優 VisualVM
jdk 調優 VisualVM

線程轉儲和堆轉儲均可以另存成檔案,以便進行離線分析。

jdk 調優 VisualVM

本文首先簡要列舉了一些性能分析相關的背景知識。然後介紹了 visualvm 的下載下傳和安裝。最後從記憶體性能、cpu 性能、快照功能以及轉儲功能四個方面展開,進一步說明了如何使用 visualvm 進行性能分析。通過本文的介紹,相信讀者對性能分析會有一定的了解,并可以利用 visualvm 進行性能分析。