天天看點

八、jdk工具之JvisualVM之四--VisualVM 進行性能分析及調優

背景知識

性能分析的主要方式

  • 監視:監視是一種用來檢視應用程式運作時行為的一般方法。通常會有多個視圖(View)分别實時地顯示 CPU 使用情況、記憶體使用情況、線程狀态以及其他一些有用的資訊,以便使用者能很快地發現問題的關鍵所在。
  • 轉儲:性能分析工具從記憶體中獲得目前狀态資料并存儲到檔案用于靜态的性能分析。Java 程式是通過在啟動 Java 程式時添加适當的條件參數來觸發轉儲操作的。它包括以下三種:
  • 系統轉儲:JVM 生成的本地系統的轉儲,又稱作核心轉儲。一般的,系統轉儲資料量大,需要平台相關的工具去分析,如 Windows 上的 windbg 和 Linux 上的 gdb。
  • Java 轉儲:JVM 内部生成的格式化後的資料,包括線程資訊,類的加載資訊以及堆的統計資料。通常也用于檢測死鎖。
  • 堆轉儲:JVM 将所有對象的堆内容存儲到檔案。
  • 快照:應用程式啟動後,性能分析工具開始收集各種運作時資料,其中一些資料直接顯示在監視視圖中,而另外大部分資料被儲存在内部,直到使用者要求擷取快照,基于這些儲存的資料的統計資訊才被顯示出來。快照包含了應用程式在一段時間内的執行資訊,通常有 CPU 快照和記憶體快照兩種類型。
  • CPU 快照:主要包含了應用程式中函數的調用關系及運作時間,這些資訊通常可以在 CPU 快照視圖中進行檢視。
  • 記憶體快照:主要包含了記憶體的配置設定和使用情況、載入的所有類、存在的對象資訊及對象間的引用關系等。這些資訊通常可以在記憶體快照視圖中進行檢視。
  • 性能分析:性能分析是通過收集程式運作時的執行資料來幫助開發人員定位程式需要被優化的部分,進而提高程式的運作速度或是記憶體使用效率,主要有以下三個方面:
  • CPU 性能分析:CPU 性能分析的主要目的是統計函數的調用情況及執行時間,或者更簡單的情況就是統計應用程式的 CPU 使用情況。通常有 CPU 監視和 CPU 快照兩種方式來顯示 CPU 性能分析結果。
  • 記憶體性能分析:記憶體性能分析的主要目的是通過統計記憶體使用情況檢測可能存在的記憶體洩露問題及确定優化記憶體使用的方向。通常有記憶體監視和記憶體快照兩種方式來顯示記憶體性能分析結果。
  • 線程性能分析:線程性能分析主要用于在多線程應用程式中确定記憶體的問題所在。一般包括線程的狀态變化情況,死鎖情況和某個線程線上程生命期内狀态的分布情況等

功能介紹

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

記憶體分析

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

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

CPU 分析

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

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

圖 7. CPU 使用情況

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

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

圖 8. CPU 性能分析結果
八、jdk工具之JvisualVM之四--VisualVM 進行性能分析及調優

線程分析

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

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

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

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

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

圖 12. 線程詳細視圖
八、jdk工具之JvisualVM之四--VisualVM 進行性能分析及調優

快照功能

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

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

  • Profiler 快照:當有一個性能分析會話(記憶體或者 CPU)正在進行時,我們可以通過性能分析結果工具欄的“快照”按鈕生成 Profiler 快照捕獲當時的性能分析資料。
  • 應用程式快照:我們可以右鍵點選左側 Applications 視窗中應用程式節點,選擇“應用程式快照”為生成一個應用程式快照。應用程式快照會收集某一時刻的堆轉儲,線程轉儲和 Profiler 快照,同時也會捕獲 JVM 的一些基本資訊。

轉儲功能

線程轉儲的生成與分析

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

圖 15. 線程标簽及線程轉儲功能

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

圖 16. 線程轉儲結果

堆轉儲的生成與分析

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

圖 17. 監視标簽及堆轉儲功能

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

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

圖 18. 堆轉儲的摘要視圖

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

圖 19. 堆轉儲的類視

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

圖 20. 選擇查詢執行個體數的類
圖 21. 執行個體數視圖

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

圖 22. 堆轉儲的
圖 23. 堆轉儲的比較結果

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

圖 24. 轉儲檔案的導出

總結

繼續閱讀