首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JVisualVM 實戰指南:從入門到記憶體洩漏深度分析與遠程監控 Tomcat

     編輯:Java 綜合教學

JVisualVM 實戰指南

JVisualVM(JDK 6u7+ 內建 `bin/jvisualvm.exe`)是基於 NetBeans 平台的可視化監控工具,整合執行緒、堆、GC、CPU、類別、MBean等功能,支援本地/遠程監控、Heap Dump 分析、記憶體洩漏定位、效能剖析。本文透過模擬洩漏案例實戰演示核心分析流程。

核心功能面板

  • Overview:JVM 參數、系統屬性、啟動參數。
  • Monitor:CPU、Heap、Metaspace、執行緒、類別載入即時圖表。
  • Threads:執行緒狀態、堆疊追蹤、死鎖偵測(紅色標記)。
  • Sampler:CPU/記憶體採樣剖析,低開銷定位熱點方法、大對象分配源。
  • Profiler:完整插桿剖析(需應用重啟),精確統計調用次數、耗時。
  • Visual GC:即時展示 Eden、Survivor、Old、Metaspace 區域 GC 行為。
  • Heap Dump:快照分析對象佔用、支配者樹、類別統計、對象引用鏈。

實戰:模擬記憶體洩漏與定位全流程

1. 洩漏代碼構造

public class CyclicDependencies {
    private static final Map<String, Object> cache = new HashMap<>(); // 靜態集合持有引用
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(10000); // 預留開啟 VisualVM 時間
        for (int phase = 1; phase <= 4; phase++) {
            for (int i = 0; i < 1_000_000 * phase; i++) {
                cache.put("key" + i, new TestMemory()); // 持續放入,永不釋放
            }
            System.out.println("phase " + phase);
            Thread.sleep(10000); // 預留 Dump 時間
        }
    }
}
class TestMemory { byte[] data = new byte[1024]; } // 每對象 1KB

JVM 參數:`-Xms512m -Xmx512m -XX:-UseGCOverheadLimit -XX:MaxPermSize=50m`

2. Visual GC 觀察老年代 GC 無效回收

  • 觀察 Old Gen 使用量持續上升,GC 次數增加但使用量不下降 → 強烈洩漏信號。
  • 對比 Phase 1 vs Phase 4 截圖:Old Gen 佔比從 30% → 95%,GC 7 次仍無法回收。

3. Sampler 定位可疑類別

  • 切換到 Sampler → Memory,按「Live Bytes」排序。
  • 發現 `TestMemory` 實例數持續增長,佔據大量記憶體。

4. Heap Dump 對比精準定位

  1. Phase 2 時 Dump → `heap-2.hprof`;Phase 4 時 Dump → `heap-4.hprof`。
  2. 載入 `heap-4.hprof` → Classes 視圖 → 右鍵 `TestMemory` → 「與另一個堆快照比較」** → 選 `heap-2.hprof`。
  3. 結果:`TestMemory` 實例新增 300 萬+,確認為洩漏源頭。

5. 反向引用鏈鎖定根因

  • 在 `TestMemory` 類別右鍵 → 「在實例視圖中顯示」** → 選任一實例。
  • 底部「References」面板顯示:`CyclicDependencies.cache` (HashMap) → `TestMemory`。
  • 結論:靜態 `cache` 集合長期持有引用,導致 GC 無法回收。

遠程監控 Tomcat 實戰配置

  1. Tomcat 啟用 JMX(`catalina.sh` 或 `setenv.sh`):
    JAVA_OPTS="$JAVA_OPTS -Djava.rmi.server.hostname=192.168.122.128 \
      -Dcom.sun.management.jmxremote.port=18999 \
      -Dcom.sun.management.jmxremote.ssl=false \
      -Dcom.sun.management.jmxremote.authenticate=false"
  2. JVisualVM 連線:右鍵「遠端」→ 新增主機 IP → 右鍵主機 → 新增 JMX 連線 → 輸入 18999 → 雙擊連線。
  3. 生產環境建議開啟 SSL 與認證(`jmxremote.password.file`、`jmxremote.access.file`)。

JVM 調優核心建議

場景策略關鍵參數
頻繁建立短命對象增大新生代-Xmn, -XX:NewRatio
大量常量/類元資料增大元空間-XX:MaxMetaspaceSize
長壽單例/快取對象多增大老年代-Xmx, -XX:NewRatio
高吞吐量(批次/計算)並行 GC-XX:+UseParallelGC
低延遲(Web/服務)並發 GC (CMS/G1/ZGC)-XX:+UseG1GC / -XX:+UseZGC

CMS 老年代建議:`-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=10`

Linux 無形介面運行 JVisualVM

  • 本地安裝 Xmanager/Xming + SSH X11 Forwarding (`ssh -X`)。
  • 或遠程複製 `.hprof` 檔案到本地分析(`jmap -dump:live,format=b,file=heap.hprof `)。
  • 確保 JVisualVM JDK 版本與目標 JVM 版本一致,避免「不受此 JVM 支援」錯誤。

掌握 JVisualVM 全功能棧,讓 JVM 調優從「玄學」變為「有據可依的工程科學」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved