1. 程式人生 > 其它 >Java 效能分析工具 Async-profiler

Java 效能分析工具 Async-profiler

如果你經常遇到 Java 線上效能問題束手無策,看著線上服務 CPU 飆升一籌莫展,發現記憶體不斷洩露滿臉茫然。別慌,這裡有一款低開銷、自帶火焰圖、讓你大呼好用的 Java 效能分析工具 - async-profiler。

最近 Arthas 效能分析工具上線了火焰圖分析功能,Arthas 使用 async-profiler 生成 CPU/記憶體火焰圖進行效能分析,彌補了之前記憶體分析的不足。在 Arthas 上使用還是比較方便的,使用方式可以看官方文件。這篇文章介紹 async-profiler 相關內容。

Arthas 火焰圖官方文件:https://alibaba.github.io/arthas/profiler.html

如果你想了解更多 Arthas 資訊,可以參考之前文章:Arthas - Java 線上問題定位處理的終極利器
async-profiler 介紹

async-profiler 是一款開源的 Java 效能分析工具,原理是基於 HotSpot 的 API,以微乎其微的效能開銷收集程式執行中的堆疊資訊、記憶體分配等資訊進行分析。

使用 async-profiler 可以做下面幾個方面的分析。

CPU cycles
Hardware and Software performance counters like cache misses, branch misses, page faults, context switches etc.
Allocations in Java Heap
Contented lock attempts, including both Java object monitors and ReentrantLocks

我們常用的是 CPU 效能分析和 Heap 記憶體分配分析。在進行 CPU 效能分析時,僅需要非常低的效能開銷就可以進行分析,這也是這個工具的優點之一。

在進行 Heap 分配分析時,async-profiler 工具會收集記憶體分配資訊,而不是去檢測佔用 CPU 的程式碼。async-profiler 不使用侵入性的技術,例如位元組碼檢測工具或者探針檢測等,這也說明 async-profiler 的記憶體分配分析像 CPU 效能分析一樣,不會產生太大的效能開銷,同時也不用寫出龐大的堆疊檔案再去進行進一步處理,。

async-profile 目前支援 Linux 和 macOS 平臺(macOS 下只能分析使用者空間的程式碼)。

Linux / x64 / x86 / ARM / AArch64
macOS / x64

async-profiler 工具在取樣後可以生成取樣結果的日誌報告,也可以生成 SVG 格式的火焰圖,在之前生成火焰圖要使用 FlameGraph 工具。現在已經不需要了,從 1.2 版本開始,就已經內建了開箱即用的 SVG 檔案生成功能。

其他資訊可以看官方文件:https://github.com/jvm-profiling-tools/async-profiler
async-profiler 安裝

下載 async-profiler 工具可以在官方的 Github 上直接下載編譯好的檔案,如果你就是想體驗手動擋的感覺,也可以克隆專案,手動編譯一下,不得不說這個工具十分的易用,我在手動編譯的過程十分順滑,沒有出現任何問題。

如果你想下載編譯好的,可以到這裡下載。

https://github.com/jvm-profiling-tools/async-profiler/releases

如果想體驗手動擋的感覺,可以克隆整個專案,進項專案編譯。

手動編譯的環境要求。

JDK
GCC

下面是手動安裝的操作命令。

執行 make 命令編譯後會在專案的目錄下生成一個 build 資料夾,裡面存放著編譯的結果。下面是我手動編譯的過程輸出。

async-profiler 使用

執行專案裡的 profiler.sh 可以看到 async-profiler 的使用幫助文件。

可以看到使用的方式是:Usage: ./profiler.sh [action] [options] ,也就是 命令+操作+引數+PID

常用的使用的幾個步驟:

  1. 檢視 java 程序的 PID(可以使用 jps )。
  2. 使用 ./profiler.sh start 開始取樣。
  3. 使用 ./profiler.sh status 檢視已經取樣的時間。
  4. 使用 ./profiler.sh stop 停止取樣,輸出結果。

這種方式使用起來多費勁啊,而且最後輸出的是文字結果,看起來更是費勁,為了不那麼費勁,可以使用幫助裡給的取樣後生成 SVG 檔案例子。

./profile.sh -d 30 -f profile.svg 3456

這個命令的意思是,對 PID 為 3456 的 java 程序取樣 30 秒,然後生成 profile.svg 結果檔案。

預設情況下是分析 CPU 效能,如果要進行其他分析,可以使用 -e 引數。

-e event	profile event: cpu|alloc|lock|cache-misses etc.

可以看到支援的分析事件有 CPU、Alloc、Lock、Cache-misses 。

async-profiler 案例

上面說完了 async-profiler 工具的作用和使用方式,既然能進行 CPU 效能分析和 Heap 記憶體分配分析,那麼我們就寫幾個不一般的方法分析試試看。看看是不是有像上面介紹的那麼好用。

Java 案例編碼

很簡單的幾個方法,hotmethod 方法寫了幾個常見操作,三個方法中很明顯 hotmethod3 方法裡的生成 UUID 和 replace(需要正則匹配)操作消耗的 CPU 效能會較多。allocate 方法裡因為要不斷的建立長度為 6萬的陣列,消耗的記憶體空間一定是最多的。

 1 package com.wdbyte.arthas;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Random;
 5 import java.util.UUID;
 6 
 7 /**
 8  * <p>
 9  * 模擬熱點程式碼
10  *
11  * @Author <a href="https://www.wdbyte.com">https://www.wdbyte.com</a>
12  */
13 public class HotCode {
14 
15     private static volatile int value;
16 
17     private static Object array;
18 
19     public static void main(String[] args) {
20         while (true) {
21             hotmethod1();
22             hotmethod2();
23             hotmethod3();
24             allocate();
25         }
26     }
27 
28     /**
29      * 生成 6萬長度的陣列
30      */
31     private static void allocate() {
32         array = new int[6 * 1000];
33         array = new Integer[6 * 1000];
34     }
35 
36     /**
37      * 生成一個UUID
38      */
39     private static void hotmethod3() {
40         ArrayList<String> list = new ArrayList<>();
41         UUID uuid = UUID.randomUUID();
42         String str = uuid.toString().replace("-", "");
43         list.add(str);
44     }
45 
46     /**
47      * 數字累加
48      */
49     private static void hotmethod2() {
50         value++;
51     }
52 
53     /**
54      * 生成一個隨機數
55      */
56     private static void hotmethod1() {
57         Random random = new Random();
58         int anInt = random.nextInt();
59     }
60 
61 }
View Code

CPU 效能分析

執行上面的程式,然後使用 JPS 命令檢視 PID 資訊。

上面執行的類名是 HotCode,可以看到對應的 PID 是 2449。

使用 ./profiler.sh -d 20 -f 2449.svg 2449 命令對 2449 號程序取樣20秒,然後得到生成的 2449.svg 檔案,然後我們使用瀏覽器開啟這個檔案,可以看到 CPU 的使用火焰圖

關於火焰圖怎麼看,一言以蔽之:火焰圖裡,橫條越長,代表使用的越多,從下到上是呼叫堆疊資訊。在這個圖裡可以看到 main 方法上面的呼叫中 hotmethod3 方法的 CPU 使用是最多的,點選這個方法。還可能看到更詳細的資訊。


可以看到 replace 方法佔用的 CPU 最多,也是程式中效能問題所在,是需要注意的地方。

Heap 記憶體分析

還是上面執行的程式,程序 PID 還是 2449,這次使用 -e 引數分析記憶體使用情況。

命令:./profiler.sh -d 20 -e alloc -f 2449-alloc.svg 2449

命令的意思是收集程序號是 2449 的程序的記憶體資訊 20 秒,然後輸出為 2449-alloc.svg 檔案。20秒後得到 svg 檔案使用瀏覽器開啟,可以看到記憶體分配情況。

依舊是橫條越長,代表使用的越多,從下到上是呼叫堆疊資訊。從圖裡可以看出來 main 方法呼叫的 allocate 方法使用的記憶體最多,這個方法裡的 Integer 型別陣列佔用的記憶體又最多,為 71%。

轉自: https://blog.csdn.net/u013735734/article/details/103452212