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

Java EE 效能測試與調優完整指南:基準測試、瓶頸定位、JVM 監控

     編輯:J2EE

效能測試目標

  • 容量目標:給定硬體下,支援最大並發數與目標回應時間 (由產品經理訂定)。
  • 擴展性目標:增加硬體資源 (CPU、記憶體、I/O、頻寬) 後,效能提升比例 (Scalability)。

基準測試 — 先測硬體極限

在業務測試前,必須量測硬體基準,否則無法判斷瓶頸在軟體還是硬體:

  1. 網路頻寬:大檔案傳輸測試實際吞吐量。
  2. CPU:複雜運算基準程式 (如加密、壓縮)。
  3. 記憶體:確認物理容量與 JVM 堆設定。
  4. I/O:磁碟讀寫速度 (dd、fio)。

基準測試腳本在調優過程中可重複執行,驗證優化成效。

業務測試案例設計

  • 並發用戶:同時在線用戶數,可能操作不同功能。
  • 事務並發:特定熱點請求 (如登入、下單) 的並發呼叫數。需依業務高峰分析熱點。

錄製真實用戶操作腳本 (JMeter, LoadRunner) 作為起點,逐步增加思考時間、資料參數化。

調優層級:由下而上

  1. OS 層:核心參數、檔案描述符限制、網路堆疊調優。
  2. JVM 層:堆大小 (-Xms/-Xmx)、GC 策略 (G1, CMS, ZGC)、JIT 編譯、類別載入。
  3. 中介軟體:連線池、執行緒池、快取 (Redis, Ehcache)、訊息佇列。
  4. 資料庫:SQL 調優、索引、分區、讀寫分離、Schema 設計。
  5. 應用演算法:鎖競爭、資料結構選擇、非同步處理、批次作業。

原則:一次只調一個參數,測試、記錄、對比。重啟後必須暖機 (Warm-up) 再測試。

監控與定位工具

  • JConsole / VisualVM / JMC:即時監控堆、執行緒、類別、GC。
  • JProfiler / YourKit / Async Profiler:CPU/記憶體分析、鎖爭用、熱點方法。
  • 應用層追蹤:自訂 TraceUtil 記錄超過閾值 (如 1 秒) 且佔比 > 20% 的方法呼叫,輸出至日誌供事後分析。

程式碼:關鍵路徑耗時記錄器

public class TraceUtil {
    private final Logger logger;
    private final long threshold = 1000; // ms
    private long begin, offtime;
    private final String threadInfo, targetId;

    public TraceUtil(Logger logger, Thread thread, String targetId, long begin) {
        this.logger = logger;
        this.threadInfo = thread.getId() + "-" + thread.getName();
        this.targetId = targetId;
        this.begin = begin;
    }

    public void trace(String event) {
        long duration = System.currentTimeMillis() - begin;
        long increment = duration - offtime;
        offtime = duration;
        float pct = (float) increment / duration * 100;
        if (duration > threshold && pct > 20) {
            logger.error("Response time too large: [{}], {}/{} ({}), {}, {}",
                threadInfo, increment, duration, pct + "%", event, targetId);
        }
    }
}

利用 ThreadMXBean 找出阻塞點

當 CPU 高但吞吐低,常因 I/O 等待或同步鎖爭用。JSP 片段示範列印所有執行緒 CPU 佔用與阻塞資訊:

<%@ page import="java.lang.management.*, java.util.*" %>
<%
ThreadMXBean mx = ManagementFactory.getThreadMXBean();
mx.setThreadContentionMonitoringEnabled(true);
ThreadInfo[] infos = mx.dumpAllThreads(false, false);
for (ThreadInfo ti : infos) {
    long cpu = mx.getThreadCpuTime(ti.getThreadId());
    out.println("Thread: " + ti.getThreadName() + "#" + ti.getThreadId()
        + " CPU: " + cpu + " ns"
        + " Blocked: " + ti.getBlockedTime() + " ms, " + ti.getBlockedCount()
        + " Lock: " + (ti.getLockInfo() != null ? ti.getLockInfo().getClassName() : "none"));
}
%>

同步鎖是常見瓶頸

大量執行緒阻塞在同一 synchronized 方法/區塊,導致 CPU 閒置。檢查自有代碼與第三方庫是否過度使用同步;改用 java.util.concurrent 非阻塞資料結構、縮小鎖範圍、採用 ThreadLocal、無鎖演算法。

參考資源

  • Java Run-time Monitoring 系列文章
  • Performance Tuning the JVM for Running Tomcat
  • 書籍 Java Performance (Charlie Hunt 等)
  • 開源監控:insideAPPS (事務級監控)、ManageEngine (企業級監控)

效能調優是系統工程,需耐心、度量、迭代,而非靠直覺猜測。

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