天天看點

使用 VisualVM 和 JProfiler 進行性能分析及調優

版權聲明:本文的内容源自于「 IBM Developer 」的博文,以對原文做重大更新,并新增 JProfiler 的内容。

概述

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

背景知識

性能分析的主要方式

  • 監視:監視是一種用來檢視應用程式運作時行為的一般方法。通常會有多個視圖(View)分别實時地顯示 CPU 使用情況、記憶體使用情況、線程狀态以及其他一些有用的資訊,以便使用者能很快地發現問題的關鍵所在。
  • 轉儲:性能分析工具從記憶體中獲得目前狀态資料并存儲到檔案用于靜态的性能分析。Java 程式是通過在啟動 Java 程式時添加适當的條件參數來觸發轉儲操作的。它包括以下三種:
    • 系統轉儲:JVM 生成的本地系統的轉儲,又稱作核心轉儲。一般的,系統轉儲資料量大,需要平台相關的工具去分析,如 Windows 上的

      windbg

      和 Linux 上的

      gdb

      等。
    • Java 轉儲:JVM 内部生成的格式化後的資料,包括線程資訊,類的加載資訊以及堆的統計資料。通常也用于檢測死鎖。
    • 堆轉儲:JVM 将所有對象的堆内容存儲到檔案。
  • 快照:應用程式啟動後,性能分析工具開始收集各種運作時資料,其中一些資料直接顯示在監視視圖中,而另外大部分資料被儲存在内部,直到使用者要求擷取快照,基于這些儲存的資料的統計資訊才被顯示出來。快照包含了應用程式在一段時間内的執行資訊,通常有 CPU 快照和記憶體快照兩種類型。
    • CPU 快照:主要包含了應用程式中函數的調用關系及運作時間,這些資訊通常可以在 CPU 快照視圖中進行檢視。
    • 記憶體快照:主要包含了記憶體的配置設定和使用情況、載入的所有類、存在的對象資訊及對象間的引用關系等。這些資訊通常可以在記憶體快照視圖中進行檢視。
  • 性能分析:性能分析是通過收集程式運作時的執行資料來幫助開發人員定位程式需要被優化的部分,進而提高程式的運作速度或是記憶體使用效率,主要有以下三個方面:
    • CPU 性能分析:CPU 性能分析的主要目的是統計函數的調用情況及執行時間,或者更簡單的情況就是統計應用程式的 CPU 使用情況。通常有 CPU 監視和 CPU 快照兩種方式來顯示 CPU 性能分析結果。
    • 記憶體性能分析:記憶體性能分析的主要目的是通過統計記憶體使用情況檢測可能存在的記憶體洩露問題及确定優化記憶體使用的方向。通常有記憶體監視和記憶體快照兩種方式來顯示記憶體性能分析結果。
    • 線程性能分析:線程性能分析主要用于在多線程應用程式中确定記憶體的問題所在。一般包括線程的狀态變化情況,死鎖情況和某個線程線上程生命期内狀态的分布情況等。

VisualVM

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

安裝方法

由于 VisualVM 已經被 Oracle 在 GitHub 上開源了,是以我們可以直接在 GitHub 上下載下傳安裝包。

進入

visualvm

的項目首頁後,點選

releases

選項:

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,點選

releases

之後,我們可以看到

visualvm

的所有穩定釋出版:

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,VisualVM 已經更新至 2.0.2 版本,我們可以選擇自己想要安裝的版本,點選下載下傳之後,自行安裝即可。

使用方法

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,以 Mac 為例,示範 VisualVM 2.0 版本的使用:

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,打開 VisualVM 之後,進入如上界面。在這裡,我們主要關注

Local

Remote

,其中:

  • Local

    ,監控本地程序;
  • Remote

    ,監控遠端程序。

預設情況下,啟動 VisualVM 之後,就會自動監控本地的 Java 程序。但是,如果我們想要監控遠端的 Java 程序,則需要進行配置。右鍵點選

Remote

,選擇

Add Remote Host

,進入如下頁面:

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,在

Host name

框中輸入我們想要監控的遠端主機的 IP,如

172.12.21.234

;至于

Display name

,我們可以了解為别名或者昵稱,自定義即可,完成後,點選

OK

按鈕:

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,連接配接到指定的主機之後,我們還需要指定想要監控的端口。右鍵點選已連接配接的主機,選擇

Add JMX Connection

,新增 Java 管理擴充連接配接,進入如下頁面:

Connection

中預設會回顯主機 IP,我們隻需要輸入想要監控的端口即可,在這裡,我們指定端口為

25600

,輸入完成後,點選

OK

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,VisualVM 已經連接配接到我們指定的主機以及端口。其中,在上圖的右側部分,已經顯示了程序的部分資訊,如 PID、Host、Main class、Java 版本和 JVM 啟動參數等。但是在這裡,我們需要特别注意一點,那就是:我們輸入的

25600

端口并不是随便輸入的,而是需要我們事先在啟動腳本或者啟動參數中配置的。具體的配置示例,如下:

-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.port=25600 \           

現在,我們已經監控到指定的程序了。接下來,我們一起來看看如何檢視更為詳細的監控資訊。首先,我們右鍵點選已經連接配接的服務:

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,右鍵菜單中展示了 Open、Sample、Thread Dump 和 Head Dump 等功能,其中:

  • Thread Dump

    ,擷取線程轉儲;
  • Head Dump

    ,擷取堆轉儲;
  • Application Snapshot

    ,擷取應用運作狀态快照。

在這裡,以

Application Snapshot

為例,點選之後,VisualVM 會生成一個應用目前運作狀态的快照,并将其存儲到

Snapshats

一欄,如上圖左側紅色方框标記所示。點選生成的快照之後,會在右側會顯示快照資訊。同樣,點選

Thread Dump

Head Dump

之後,會生成對應的線程轉儲和堆轉儲,隻不過存儲的位置會略有不同。

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,我們看 VisualVM 的右側頁面,包括 Overview、Monitor、Threads、Sampler 和 Visual GC 等,其中:

  • Overview

    ,程序資訊概覽,包括 JDK 版本、JVM 啟動參數和環境變量配置等資訊;
  • Monitor

    ,圖形化監控頁面,包括 CPU、記憶體、類以及線程等資訊,可以手動觸發 GC 以及執行堆轉儲;
  • Threads

    ,線程資訊,可以查詢程序内線程活動情況,可以執行線程轉儲;
  • Sampler

    ,采樣器,可以實時采集 CPU、記憶體等資訊;
  • Visual GC

    ,監控垃圾收集情況,想要使用此功能需要我們事前在啟動腳本或者啟動指令中進行配置。

上圖就是 Overview 頁面的内容。接下來,我們再來看看 Monitor、Threads 以及 Sampler 的頁面。

Monitor

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,就是 Monitor 頁面的内容,包括 CPU、Memory、Classes 和 Threads,其中:

  • CPU

    ,實時顯示 CPU 使用率以及 GC 活動比例;
  • Memory

    ,實時顯示堆使用情況,包括

    Metaspace

    ,JDK 8 之前是

    PermGen

  • Classes

    ,實時顯示類加載情況;
  • Threads

    ,實時顯示線程的數量,包括總線程數量以及守護線程數量。

在這裡,我們可以通過勾選上面的選擇框自定義顯示樣式,像上面就僅勾選了

CPU

Threads

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,勾選了

CPU

Memory

Classes

Threads

四個選項。同時,我們也可以點選

Perform GC

按鈕,手動觸發 GC;點選

Heap Dump

按鈕,可以導出堆轉儲資訊。

Threads

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,就是 Threads 頁面的内容,顯示了線程的活躍情況。同時,點選

Thread Dump

,可以導出線程轉儲資訊

Sampler

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,就是 Sampler 頁面的内容,可以采集 CPU 和記憶體的資訊。當我們點選

CPU

或者

Memory

按鈕之後,開始執行采樣,點選

Stop

即可結束采樣。上圖為 CPU 采樣的結果,顯示了各個線程占用 CPU 的情況;點選

Memory

,可以切換到記憶體的采樣結果:

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,就是記憶體的采樣結果,顯示各個類型對象占用的記憶體情況。

同樣,在 Sampler 頁面,我們也可以找到手動觸發 GC、導出堆轉儲以及線程轉儲的按鈕。

JProfiler

JProfiler 是由 EJ 技術有限公司針對 Java 應用程式開發的性能監控工具,可以對 JVM 進行精确的監控,其中堆周遊、CPU 剖析、線程剖析是定位目前系統瓶頸的有效手段。與 Oracle 開源的 VisuaVM 相比,JProfiler 的功能更為強大,但 JProfiler 卻是一個重量級的 JVM 監控工具,當啟動 JProfiler 監控的時候,會使得 CPU 的使用率顯著飙升。

首先,進入 EJ 官方的 JProfiler 下載下傳位址:

點選上述連結後,進入如下頁面:

使用 VisualVM 和 JProfiler 進行性能分析及調優

如上圖所示,自行選擇需要安裝的版本,然後點選

DOWNLAOD

按鈕,下載下傳 JProfiler 安裝包。

特别地,JProfiler 需要激活使用,至于激活的方法,網上有很多,大家自己搜尋即可。

Em.....,網上有很多,我就先不寫了,直接給出一些連結,大家跳過去參考下吧,捂臉!

如上述連結所示,這是我感覺寫的很不錯的兩篇文章,在此分享給大家。

參考資料: