CodeGym /課程 /JAVA 25 SELF /JVM 監控:JMX、VisualVM、Java Flight Recorder

JVM 監控:JMX、VisualVM、Java Flight Recorder

JAVA 25 SELF
等級 63 , 課堂 3
開放

1. JMX (Java Management Extensions): JVM 監控的核心

監控就像為你的應用程式做定期健檢。若把日誌記錄比作「已經發生的事情」的日記,監控則是一組儀表,會即時顯示系統此刻的狀態:溫度、脈搏、血壓、血糖以及其他對 JVM 至關重要的指標。

它有助於了解實際使用了多少記憶體、有沒有洩漏、目前有多少執行緒以及它們的狀態——在等待、執行還是被鎖住。你可以看到垃圾回收器的觸發頻率、CPU 的負載,並及時察覺像是記憶體或執行緒數量突然上升之類的警訊。

簡而言之,記錄告訴你已經發生了什麼,而監控則顯示此刻正在發生什麼

JMX 基礎:是什麼,為什麼需要

JMX 是 Java 中的一項技術,能讓你從內部觀察應用程式的運作,甚至進行少量控制。它透過特殊物件——MBean(Management Bean)——工作。可以把它看作 JVM 內部的「感測器」與「開關」:有些用來顯示系統狀態,有些則能稍作調整。

透過 JMX,你可以得知當前 JVM 分配了多少記憶體、多少執行緒處於活躍狀態、垃圾回收花了多少時間等等——無需修改程式碼或重啟應用程式。

它如何運作

JVM 中「開箱即用」就有許多 MBean,可提供下列資訊:

  • 記憶體(heapnon-heap);
  • 垃圾回收器(GC);
  • 執行緒;
  • 類別(載入/卸載數量);
  • 甚至是 JVM 本身(版本、啟動參數)。

JMX 就像車上的儀表板。 你能看到速度、轉速、引擎溫度——而這些都可透過標準感測器(MBean)取得。

如何存取 JMX

最簡單的方式是使用隨 JDK 提供的標準工具 JConsole

啟動 JConsole

  1. 打開終端機/命令列。
  2. 執行指令:
    jconsole
    
  3. 選擇你想監控的 Java 行程(例如你的應用程式)。

JConsole 會透過 JMX 連線到 JVM,並顯示圖表與表格:記憶體使用量、執行緒數量、垃圾回收器活動等。

範例:查看記憶體與執行緒

JConsole 中打開 "Memory""Threads" 分頁。你會看到已用記憶體的變化、目前有多少執行緒存活、哪些活躍、哪些在等待。

自訂 MBean

你可以建立自己的 MBean 來監控自家指標(例如已處理訂單數)。不過這屬於進階主題:標準的 MBean 已經提供了非常多資訊。

2. VisualVM — 視覺化監控與剖析

如果 JConsole 是「儀表板」,那 VisualVM 就是一整套包含 X 光、MRI 與血液分析的診斷中心。它不只用於監控,還能剖析應用程式、擷取 heap dump、分析洩漏,並查看哪些方法最耗時。

安裝與啟動 VisualVM

  • VisualVM 通常隨 JDK 提供(一般為 jvisualvm),但也可於 visualvm.github.io 下載最新版本。
  • 以以下指令啟動:
    jvisualvm
    
  • 啟動後,你會看到本機上所有已啟動的 Java 行程清單。

連線到行程

  1. 在清單中找到你的行程(例如 MainMyApp)。
  2. 雙擊它——會開啟該行程的資訊分頁。
  3. 完成!現在你可以看到:
    • 即時的 CPU 與記憶體使用狀況。
    • 執行緒數量與其狀態。
    • 已載入的類別清單。
    • 能夠擷取 heap dumpthread dump

VisualVM 的主要功能

使用 VisualVM 可以觀察記憶體的使用情況——包含 heapnon-heap。圖表可顯示消耗是在成長還是趨於穩定。若想檢查垃圾回收,按下 "Perform GC" 按鈕——JVM 會立即嘗試清理記憶體。你也可以建立 heap dump(記憶體快照)並加以分析以找出洩漏。

它也會顯示執行緒狀態:目前啟動了多少、哪些在運作、哪些在等待或被鎖住。若發生 deadlockVisualVM 能協助偵測並顯示互鎖。

要做深入分析可以使用剖析器:你會看到「熱點」方法,也就是最耗費 CPU 時間或記憶體的方法。這在診斷性能突然下降時特別有用。

範例:監控一個迷你應用

public class MemoryLeakDemo {
    public static void main(String[] args) throws InterruptedException {
        List<byte[]> memoryConsumers = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            memoryConsumers.add(new byte[1024 * 1024]); // 1 MB
            Thread.sleep(100); // 稍微等待,讓圖表更平滑
        }
        System.out.println("完成!別忘了到 VisualVM 看看 :)");
        Thread.sleep(60000); // 保持應用程式開著以便分析
    }
}

現在:

  1. 啟動程式。
  2. 打開 VisualVM,連線到該行程。
  3. 觀察記憶體使用量如何成長。
  4. 擷取 heap dump,找出佔用記憶體的陣列。

3. Java Flight Recorder (JFR):JVM 的黑盒

什麼是 JFR

Java Flight Recorder 是內建於 JVM 中,用於收集應用程式運作事件的工具。它就像「黑盒」:JFR 會記錄在 JVM 中發生的事情,之後可用來找出瓶頸或事故原因。

JFR 會收集:

  • GC 事件;
  • 執行緒資訊;
  • 方法呼叫頻率與時間剖析;
  • 停頓與延遲;
  • 例外與錯誤。

如何啟用 JFR

自 Java 11 起,OpenJDK 已內建 JFR

搭配 JFR 啟動

java -XX:StartFlightRecording=filename=recording.jfr,duration=60s,settings=profile -jar MyApp.jar
  • filename=recording.jfr — 存放錄製檔的位置。
  • duration=60s — 錄製時長。
  • settings=profile — 詳細程度(defaultprofilecontinuous)。

查看結果

要分析 .jfr 檔,可使用 JDK Mission ControlJMC):

  1. 下載 JMCjdk.java.net/jmc
  2. 打開檔案 recording.jfr
  3. 檢視圖表、「熱點」方法、GC 停頓與執行緒活動。

範例:擷取「黑盒」

  1. 使用 JFR 啟動應用程式(見上方指令)。
  2. 打開 JDK Mission Control,載入錄製檔。
  3. 評估 CPU/記憶體的「熱點」、垃圾回收頻率以及活躍執行緒數量。

4. 實作:監控一個應用

import java.util.ArrayList;
import java.util.List;

public class MonitoringExample {
    public static void main(String[] args) throws InterruptedException {
        List<byte[]> memory = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            memory.add(new byte[2 * 1024 * 1024]); // 2 MB
            Thread.sleep(500);
        }
        // 啟動一個執行緒
        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(1000);
                    System.out.println("背景執行緒在運作...");
                } catch (InterruptedException e) {
                    break;
                }
            }
        }).start();

        Thread.sleep(20000); // 保持應用程式開著以便監控
    }
}

操作步驟:

  • 啟動程式。
  • 打開 VisualVM,找到行程,查看記憶體圖與執行緒。
  • 嘗試擷取 heap dumpthread dump
  • 進階:搭配 JFR 啟動並在 JMC 中查看結果。

5. 實用細節

監控工具比較表

工具 適用於 如何啟動 特色
JConsole (JMX) JVM 基本指標、執行緒、GC
jconsole
簡單、隨 JDK 提供
VisualVM 監控、剖析、heap dump
jvisualvm
圖表、記憶體/CPU 分析
Java Flight Recorder JVM 事件的深入分析
java -XX:StartFlightRecording...
在 JMC 中分析,「黑盒」
JDK Mission Control 查看 JFR 檔案 獨立程式 詳細分析與報告

建議

  • 不只在正式環境,在測試階段也要監控。 這樣能更早抓到記憶體洩漏與「卡住」的執行緒。
  • Heap dump 一點也不可怕! 懷疑洩漏時就擷取記憶體傾印,並在 VisualVM 中分析。
  • 別害怕嘗試使用 JFR。 即使一開始看不懂,事件與圖表也能幫你找出瓶頸。
  • JMX 可以程式化使用。 例如把指標傳送到 Prometheus/Grafana
  • 剖析器不適合長期常駐。 請在需要時才啟用,否則應用程式可能變慢。

6. 監控 JVM 的常見錯誤

錯誤 1:完全不監控。 許多新手認為只要應用程式「能跑」,一切就沒問題。其實記憶體與執行緒問題常在高負載或一段時間後才顯現。別偷懶,至少偶爾打開 VisualVM/JConsole 看一下。

錯誤 2:在大型應用上毫無準備就擷取 heap dump。 大型應用的 heap dump 可能以 GB 計,還可能讓行程「凍住」數秒。請在測試環境進行,或若是正式環境,選擇離峰時段。

錯誤 3:忽視 GC 與執行緒指標。 長時間高比例的 GC 開銷是警訊!若執行緒數量穩定成長——請找出執行緒洩漏。

錯誤 4:不分析監控結果。 只打開 VisualVM 還不夠。檢視哪些物件佔用記憶體、哪些方法「吃」了 CPU、為什麼出現 deadlock。請剖析堆疊追蹤與根因。

錯誤 5:在正式環境不加思索地使用剖析器。 剖析可能顯著拖慢應用程式。只在診斷時啟用,而非長期常駐。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION