JDK1.6 OPTS 參數效能調校

Java 參數 OPTS 說明

在Java應用開發中,合理配置JVM記憶體參數是確保應用穩定性和性能的關鍵。

Bash
JAVA_OPTS=%JAVA_OPTS% -Xms768m -Xmx8192m -XX:MaxNewSize=384m -XX:MaxPermSize=384m

JAVA_OPTS=%JAVA_OPTS% ...的意思是「保留原本已經設定好的 JAVA_OPTS 參數,並在後面接著加上新的參數」。這樣做可以避免覆蓋掉之前原有的設定。

這行指令是在 Windows 環境(如批次檔 .bat)中用來設定 Java 虛擬機(JVM)啟動參數的環境變數。它的主要作用是調整 Java 程式的記憶體分配,以提升系統效能或防止記憶體不足(OutOfMemoryError)。

記憶體參數詳細說明

參數意思設定值說明
-Xms768m初始堆記憶體大小 (Initial Heap Size)程式啟動時,JVM 就會直接向作業系統申請 768 MB 的堆記憶體。
-Xmx8192m最大堆記憶體大小 (Maximum Heap Size)該 Java 程式上限最多可以使用 8192 MB (即 8 GB) 的堆記憶體。
-XX:MaxNewSize=384m最大新生代記憶體大小 (Max New Generation Size)限制堆記憶體中「新生代(New/Young Generation,用於存放新建立的物件)」的最大範圍為 384 MB。
-XX:MaxPermSize=384m最大永久代記憶體大小 (Max Permanent Generation Size)限制「永久代(Permanent Generation,用於存放類別類別、靜態變數等)」的最大範圍為 384 MB。

補充注意事項(針對 Java 版本)

  1. -XX:MaxPermSize 在新版 Java 已失效:
    • 這個參數只在 Java 7(含)以前 的版本有效。
    • 從 Java 8 開始,JVM 移除了永久代(PermGen),改用元空間(Metaspace)。如果你使用的是 Java 8 或更新的版本,這個參數會被忽略,且應該改用 -XX:MaxMetaspaceSize=384m。
  2. 記憶體單位:
    • 參數末尾的 m 代表 MB (Megabytes)。

配置範例

Linux 的配置範例

Bash
#!/bin/bash
JAVA_OPTS="
  -Xms1g 
  -Xmx1g 
  -XX:MetaspaceSize=128m 
  -XX:MaxMetaspaceSize=512m 
  -Xss512k 
  -XX:MaxDirectMemorySize=512m
"
echo "啟動参数: $JAVA_OPTS"
java $JAVA_OPTS -jar "C:\path\to\your-application.jar"

Windows 上的配置範例

Bash
$Xms = "1g"
$Xmx = "1g"
$MetaspaceSize = "128m"
$MaxMetaspaceSize = "512m"
$Xss = "512k"
$MaxDirectMemorySize = "512m"

$javaOpts = "-Xms$Xms -Xmx$Xmx -XX:MetaspaceSize=$MetaspaceSize -XX:MaxMetaspaceSize=$MaxMetaspaceSize -Xss$Xss -XX:MaxDirectMemorySize=$MaxDirectMemorySize"
Write-Host "啟動参数: $javaOpts"
java $javaOpts -jar "C:\path\to\your-application.jar"

常見問題

  • OutOfMemoryError: Java heap space

原因:堆記憶體不足或記憶體洩漏。解決:增大 -Xmx 或分析堆轉儲(-XX:+HeapDumpOnOutOfMemoryError)

  • OutOfMemoryError: Metaspace

原因:元空間不足。解決:增大 -XX:MaxMetaspaceSize

案例說明

在 Host 上安裝 VMware ESXi, 7.0.3 並開立一個 Guest: Windows server 2019

  • 賦予 4 個 執行緒(vCPU)
  • 記憶體 16 GB
  • JDK 1.6.0_21

在 JDK 1.6 (64-bit) 的環境下,主機擁有 16 GB RAM 與 4 vCPU,屬於相當充足的硬體資源。由於 JDK 1.6 的垃圾回收器(GC)演算法與記憶體管理機制較為老舊,如果記憶體一口氣給得太大(例如超過 12GB),反而容易在發生 Full GC 時導致嚴重的「系統停頓(Stop-The-World)」。

針對硬體配置,以下提供一個平衡穩定性與效能的標準建議配置,以及專門針對 4 vCPU 的優化參數:

推薦的 JAVA_OPTS 配置

Bash
SET JAVA_OPTS=%JAVA_OPTS% -Xms6144m -Xmx6144m -Xmn2048m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:ParallelGCThreads=8 -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly

參數配置原因與核心邏輯

將參數拆解為三大面向來說明:

堆記憶體優化(Heap Allocation)

-Xms6144m -Xmx6144m (6 GB)

  • 將初始與最大堆記憶體設為相同值,可以避免 JVM 在執行過程中頻繁向作業系統申請或釋放記憶體,減少效能抖動。
  • 為什麼不給到 10G 或 12G? JDK 1.6 的 CMS 回收器在處理超大記憶體時,萬一觸發 Full GC,停頓時間可能會長達數秒甚至數十秒。6 GB 到 8 GB 是 JDK 1.6 兼顧容量與 GC 停頓時間的黃金比例。

-Xmn2048m (2 GB)

  • 這是新生代(New Generation)的大小(等同於同時設定了 NewSize 與 MaxNewSize)。在 JDK 1.6 中,直接使用 -Xmn 是更標準且明確的寫法。
  • 將新生代設為整個堆記憶體的 1/3(2GB / 6GB),能確保有足夠的空間存放短生命週期的物件,避免它們過早流入老年代(Old Gen)引發 Full GC。

非堆記憶體優化(Non-Heap)

  • -XX:PermSize=512m -XX:MaxPermSize=512m (512 MB)

JDK 1.6 非常依賴永久代(PermGen)來存放 Class 資訊。如果您的應用程式使用了大量的框架(如 Spring、Hibernate)或有動態生成代理類別(Cglib),512MB 是比較安全的保險數字,同樣建議將初始與最大值設為一致以防震盪。

垃圾回收與 8 vCPU 多執行緒優化(GC & CPU Tuning)

-XX:+UseConcMarkSweepGC -XX:+UseParNewGC

啟用 CMS (Concurrent Mark Sweep) 垃圾回收器。這是 JDK 1.6 面對多核心、大記憶體 Web 服務時,降低停頓時間(Low-Pause)的最佳選擇。它會搭配 ParNew 來並行回收新生代。

-XX:ParallelGCThreads=8

指定並行 GC 的執行緒數量。因為您有 8 vCPU,直接設定為 8 可以完全發揮多核心的優勢,加速新生代的垃圾回收速度。

-XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly

  • 控制老年代記憶體用到 70% 時就「提前」觸發 CMS 垃圾回收。
  • 重要原因:CMS 是與應用程式並行運作的,如果在老年代快滿了(如 90%)才回收,可能會因為空間不足而引發 Concurrent Mode Failure,迫使 JVM 退回到最慢的單執行緒 Full GC。設定 70% 可以預留 30% 的緩衝空間。

實務監控建議

這配置留了約 8-9 GB 的記憶體給作業系統快取(OS Cache)、執行緒堆疊(Thread Stack)以及可能的其他程序,對 16GB 的主機來說非常安全。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *