常用 Java Profiling 工具的分析與比較

在 Java 程序的開發過程中,不可避免地會遇到內存使用、性能瓶頸等問題。Java Profiler 工具能幫助開發人員快速、有效地定位這些問題,因此成爲了 Java 開發過程中的一個重要工具。目前市場上的 Java Profiler 工具種類繁多,本文將對目前比較常見的幾種工具進行簡要介紹,並從功能、性能等角度作比較,從而幫助 Java 程序員選擇合適的 Java Profiler 工具。

本文主要分爲三個部分:第一部分簡要介紹 Java Profiler 工具的原理;第二部分對目前常見的 Java Profiler 工具 TPTP, CodePro Profiler, YourKit Java Profiler, JProfiler 進行簡要介紹;第三部分對以上工具從不同的角度進行比較,幫助開發人員選擇合適的工具。

相對於靜態代碼分析,Profiling 是通過收集程序運行時的信息來研究程序行爲的動態分析方法。其目的在於定位程序需要被優化的部分,從而提高程序的運行速度或是內存使用效率。收集程序運行時信息的方法主要有以下三種:

  • 事件方法:對於 Java,可以採用 JVMTI(JVM Tools Interface)API 來捕捉諸如方法調用、類載入、類卸載、進入 / 離開線程等事件,然後基於這些事件進行程序行爲的分析。
  • 統計抽樣方法(sampling): 該方法每隔一段時間調用系統中斷,然後收集當前的調用棧(call stack)信息,記錄調用棧中出現的函數及這些函數的調用結構,基於這些信息得到函數的調用關係圖及每個函數的 CPU 使用信息。由於調用棧的信息是每隔一段時間來獲取的,因此不是非常精確的,但由於該方法對目標程序的干涉比較少,目標程序的運行速度幾乎不受影響。
  • 植入附加指令方法(BCI): 該方法在目標程序中插入指令代碼,這些指令代碼將記錄 profiling 所需的信息,包括運行時間、計數器的值等,從而給出一個較爲精確的內存使用情況、函數調用關係及函數的 CPU 使用信息。該方法對程序執行速度會有一定的影響,因此給出的程序執行時間有可能不準確。但是該方法在統計程序的運行軌跡方面有一定的優勢。

目前市面上的 Java Profiler 工具採用的信息收集方法通常是以上三種方法的任意組合。

Profiler 工具功能簡介

雖然市場上的 Java Profiler 工具有不少,但是基本功能大多相似,本節首先對這些基本功能進行介紹。

  • 遙測(Telemetry):遙測是一種用來查看應用程序運行行爲的最簡單的方法。通常會有多個視圖(View)分別實時地顯示 CPU 使用情況、內存使用情況、線程狀態以及其他一些有用的信息,以便用戶能很快地發現問題的關鍵所在。
    • CPU Telemetry 視圖一般用於顯示整個應用程序的 CPU 使用情況,有些工具還能顯示應用程序中每個線程的 CPU 使用情況。
    • Memory Telemetry 視圖一般用於顯示堆內存和非堆內存的分配和使用情況。
    • Garbage Collection Telemetry 視圖顯示了 JVM 中垃圾收集器的詳細信息。
    • Threads Telemetry 視圖一般用於顯示當前運行線程的個數、守護進程的個數等信息。
    • Classes Telemetry 視圖一般用於顯示已經載入和還沒有載入的類的數量。
  • 快照(snapshot):應用程序啓動後,profiler 工具開始收集各種執行數據,其中一些數據直接顯示在遙測視圖中,而另外大部分數據被保存在內部,直到用戶要求獲取快照,基於這些保存的數據的統計信息才被 顯示出來。快照包含了應用程序在一段時間內的執行信息,通常有兩種類型的快照:CPU 快照和內存快照。
    • CPU 快照主要包含了應用程序中函數的調用關係及運行時間,這些信息通常可以在 CPU 快照視圖中進行查看。
    • 內存快照則主要包含了內存的分配和使用情況、載入的所有類、存在的對象信息及對象間的引用關係。這些信息通常可以在內存快照視圖中進行查看。
  • CPU Profiling:CPU Profiling 的主要目的是統計函數的調用情況及執行時間,或者更簡單的情況就是統計應用程序的 CPU 使用情況。通常有兩種方式來顯示 CPU Profiling 結果:CPU 遙測和 CPU 快照。
  • 內存 Profiling:內存 Profiling 的主要目的是通過統計內存使用情況檢測可能存在的內存泄露問題及確定優化內存使用的方向。通常有兩種方式來顯示內存 Profiling 結果:內存遙測和內存快照
  • 線程 Profiling:線程 Profiling 主要用於在多線程應用程序中確定內存的問題所在。 一般包括三個方面的信息:
    • 某個線程的狀態變化情況
    • 死鎖情況
    • 某個線程在線程生命期內狀態的分佈情況
  • Profiling 的啓動設置:類似於 eclipse 中 Run 和 Debug 的啓動設置,進行 Profiling 之前也需要進行啓動設置,包括:profiling 的模式 (CPU profiling 或內存 profiling),信息獲取類型(遙測 , 抽樣統計或者 BCI ) 等等。
  • Profiler Preference 設置:主要用於 Profiler 過濾器(選擇需要關注的包、類)、取樣間隔時間的設置等。

Java Profiler 工具介紹

本文接下來將對目前市場上常見的幾種 Java Profiler 工具進行介紹。

TPTP

TPTP(Test and Performance Tools Platform)是 eclipse 官方的 Profiling 工具插件。TPTP 提供了諸如測試,追蹤(trace),性能測試,圖形界面性能分析等功能。同時 TPTP 還是一個可擴展的開發平臺框架,你可以對它加以擴展集成到你自己的產品中。TPTP 可以通過 Eclipse update Manager 或者是安裝包進行安裝,安裝成功後會在 eclipse 中增加如下所示的按鈕,另外一個專門的用於檢查 TPTP profiling 結果的 perspective 也會添加進 eclipse 中,如下圖所示:


圖 1. TPTP
圖 1. TPTP

CodePro Profiler

CodePro Profiler 是由 instantiations 公司推出的一款商用 eclipse 插件,它可以通過 Eclipse update Manager 進行安裝或者是將安裝包直接解壓縮後保存在 eclipse 的指定目錄下。與 TPTP 類似,安裝成功後,有一個專門的用於查看 CodePro profiling 結果的 perspective 會添加進 eclipse 中,如下圖所示:


圖 2. CodePro
圖 2. CodePro

YourKit Profiler

YourKit Java Profiler 也是一款商用軟件,支持的操作系統包括:Windows, Linux, FreeBSD, Mac OS X, Solaris 以及 HP-UX;支持的 IDE 包括:Eclipse, JBuilder, JDeveloper, NetBeans 以及 Intellij IDEA。安裝成功且首次啓動 YourKit Java Profiler 後,會彈出一個對話框,讓用戶選擇 YourKit Java Profiler 要集成進的 IDE,並指定該 IDE 的安裝路徑,點擊”Install Plugin”按鈕並集成成功之後,Eclipse 中會出現如下圖標,用戶就可以從 Eclipse 中啓動 Profiling,但是 profiling 的結果需要在 YourKit Java Profiler 中進行查詢,如下圖所示:


圖 3. YourKit
圖 3. YourKit

JProfiler

JProfiler 是由 ej-technologies 推出的一款商用軟件,支持的操作系統有:Windows, Linux, Mac OS X, FreeBSD, Solaris, AIX 以及 HP-UX;支持的 IDE 包括:Eclipse, NetBeans, Intellij IDEA, JBuiler 以及 JDeveloper。安裝成功並首次啓動 JProfiler 後,會彈出一個設置界面,當完成左欄所示的那些步驟後,Eclipse 中就會出現如下圖標,用戶就可以從 Eclipse 中啓動 Profiling。與 YourKit Java Profiler 類似,profiling 的結果需要在 JProfiler 中進行查詢,如下圖所示:


圖 4. JProfiler
圖 4. JProfiler

Java Profiler 工具比較

本章節將從如下幾個方面對上述工具進行比較:

  • 與 Eclipse 的集成性
    • TPTP:是一款基於 Eclipse 開發的插件,因此與 eclipse 的集成性很好。安裝成功後,對 TPTP 的一切設置與操控都可以在 eclipse 中完成;另外,profiling 的結果也可以在 eclipse 中進行查詢。
    • CodePro Profiler: 與 TPTP 類似,CodePro Profiler 也是一款基於 eclipse 開發的插件,因此與 eclipse 的集成性很好好。用戶在 eclipse 中就可以完成對 profiling 的所有操作。
    • YourKit Java Profiler: YourKit Java Profiler 可以說是一個比較獨立的工具,安裝成功後,用戶可以直接在 eclipse 中啓動 YourKit Java Profiler 並對 profiling 選項進行配置,但是用戶必須在 YourKit Java Profiler 工具中對 Profiling preferrence 進行配置,而且 profiling 信息必須在 YourKit Java Profiler 中進行查看。因此和 Eclipse 的集成度一般。
    • JProfiler: JProfiler 也是一款比較獨立的工具,安裝成功後,用戶可以直接在 eclipse 中啓動 JProfiler,其他所有操作必須回到 JProfiler 工具中進行。因此和 Eclipse 的集成性不好。
  • 遙測種類
    • TPTP:目前使用的 4.6.2 的版本只提供了線程 Telemetry。
    • CodePro Profiler: 總共有五個類型:CPU, 內存 , 線程 , 載入的類以及垃圾收集。
    • YourKit Java Profiler: 與 CodePro Profiler 相比,缺少載入類的監測。
    • JProfiler: 與 CodePro Profiler 一樣,總共有五個類型的監測方法。
  • CPU 快照包含的統計數據類型
    • TPTP: CPU 快照包含的統計數據有:
      • 包的組成關係,細化到包含的類及類中的方法。
      • 方法的調用關係:以每個線程爲根節點的方法調用信息,對於樹中出現的代表方法的每個節點,列出了該方法的運行時間或運行時間百分比,以及該方法被調用的次數。
      • 方法被調用情況:列出了直接調用某方法的其他方法,以及這些方法調用該方法的次數及相關運行時間。
      • 熱點列表:包含了 CPU 佔用時間排列前十的方法、類或包。
    • CodePro Profiler: CPU 快照包含的統計數據類型有:
      • 包的組成關係,細化到包含的類及類中的方法。
      • 方法的調用關係。以樹結構表示,根據根節點表示的對象的不同,分爲三種類型:以每個線程爲根節點的方法調用關係,以整個線程爲根 節點的方法調用關係,以及以每個方法爲根節點的方法調用關係。對於樹中出現的代表方法的每個節點,列出了該方法的運行時間或運行時間百分比,以及由該方法 生成的對象個數和爲這些對象分配的內存大小。
      • 方法的被調用關係。該關係以樹結構表示,其中根節點爲某個指定的方法,每個節點的子節點爲父節點的調用者。
      • 熱點列表:包含了 CPU 佔用時間排前的一些方法。
    • YourKit Java Profiler:CPU 快照包含的統計數據類型與 CodePro Profiler 類似;
    • JProfiler:與 CodePro Profiler 相比,缺少以每個方法爲根節點的方法調用關係。因此當要查看以某個方法爲調用起點的調用關係時,需要到以線程爲根的樹結構當中去查找。另外,方法的被調用 關係不是以樹結構來表示的,而是以圖的方式來顯示的,當調用關係比較複雜的時候,很難在一個屏幕中看到一個全局關係圖。
  • 內存快照包含的統計數據類型
    • TPTP:包含了類實例的內存分配情況,包括實例化的對象個數,以及這些對象的本身佔用內存的大小。相對於其它 Java Profiler 工具,TPTP 的內存快照包含的統計數據類型比較少。
    • CodePro Profiler: 包含的統計數據有
      • 類實例的內存分配情況,包括實例化的對象個數,以及這些對象的 shallow 和 retained 大小。(Shallow size 就是對象本身佔用內存的大小,不包含對其他對象的引用;Retained size 是該對象自己的 shallow size,加上從該對象能直接或間接訪問到的 shallow size 之和,即該對象被 GC 之後所能回收到內存的總和)。
      • 最大對象列表:包含了 retained 大小排前的一些對象。
      • 有可能存在內存泄漏的對象列表:包含了有可能存在內存泄漏的對象以及可能性大小。
    • YourKit Java Profiler:與 CodePro Profiler 相比,缺少內存泄露對象列表這一項。
    • JProfiler:與 CodePro Profiler 相比,缺少 retained size 統計數據及內存泄露對象列表。
  • 源代碼定位功能,即在快照中選中某個類、成員變量或者方法時,可以在源代碼中定位到對應的定義。
    • TPTP:只能定位到某個類,無法定位到方法或其中的成員變量。
    • CodePro Profiler: 擁有該功能,但是隻能定位到類及成員變量,無法定位到方法。
    • YourKit Java Profiler:可以定位到類、成員變量及方法。
    • JProfiler:與 CodePro Profiler 類似。
  • 快照操作,主要從快照的獲取、快照的保存及快照的比較這三方面進行比較。
    • TPTP:當應用程序啓動後,用戶可以選擇在適當的時候進行快照獲取;這些快照不會自動保存,因此當 eclipse 關閉後,這些快照數據將會消失,但是用戶可以通過 export 的方式將需要的快照保存下來。
    • CodePro Profiler: 當應用程序啓動後,用戶可以選擇在適當的時候進行快照獲取;這些快照會被自動保存在 Eclipse Workspace 之外的一個臨時的空間,當 eclipse 關閉後,這些快照將會消失,用戶可以通過 export 的方式將需要的快照保存下來;CodePro Profiler 還提供了快照的比較功能,不過前提是這兩個快照的類型必須相同(例如:都是以 sampling 模式或 BCI 模式運行的)。
    • YourKit Java Profiler:當應用程序啓動後,用戶可以選擇在適當的時候進行快照獲取,針對內存快照,YourKit Java Profiler 還提供了自動獲取快照的功能;這些快照會被自動保存到一個臨時的文件夾中,eclipse 關閉後,這些文件不會消失;另外,YourKit Java Profiler 也提供了快照比較功能。
    • JProfiler:工具會要求你指定一個目錄來保存該 snapshot。
  • 性能,在 sampling 模式下,這些工具的性能相差不大,這裏主要比較在 BCI 模式下的性能。
    • TPTP:目前使用的 4.6.2 的版本沒有 BCI 模式。
    • CodePro Profiler:當程序比較大的情況下,採用 BCI 模式進行 profiling 的速度比較慢;另外,在獲取內存泄露候選者的時候,速度也是相當慢。(當程序代碼量 5 萬行時,用 CodePro Profiler 進行 Profiling 需要 5 分鐘,在獲取內存泄露候選者時,需要花費 20 分鐘)
    • YourKit Java Profiler:BCI 模式下的運行速度還可以。(當程序代碼量爲 5 萬行時,需要 1 分鐘)
    • JProfiler:感覺不出程序運行速度受影響。(當程序代碼量爲 5 萬行時,需要半分鐘)
  • 健壯性,採用 CodePro Profiler 對比較大的應用程序進行 profiling 時,很容易出現棧溢出的錯誤。

結論

TPTP 是一款基於 eclipse 的開源軟件,且提供的功能比較簡單,因此適用於基於 eclipse 開發的應用程序,且該應用程序比較簡單的情況;Codepro Profiler 提供的功能相對來說比較豐富,且與 eclipse 的集成性很好,但是在性能方面有待改善,因此適用於基於 eclipse 開發的應用程序,且對性能要求不高的情況;YourKit Java Profiler,JProfiler 與 Eclipse 的集成性都屬於一般,提供的功能也比較豐富,且性能不錯,因此適用於對 eclipse 集成度要求不高,且對性能要求較高的情況。

發佈了44 篇原創文章 · 獲贊 4 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章