Java 參數 OPTS 說明
在Java應用開發中,合理配置JVM記憶體參數是確保應用穩定性和性能的關鍵。
JAVA_OPTS=%JAVA_OPTS% -Xms768m -Xmx8192m -XX:MaxNewSize=384m -XX:MaxPermSize=384mJAVA_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 版本)
-XX:MaxPermSize在新版 Java 已失效:- 這個參數只在 Java 7(含)以前 的版本有效。
- 從 Java 8 開始,JVM 移除了永久代(PermGen),改用元空間(Metaspace)。如果你使用的是 Java 8 或更新的版本,這個參數會被忽略,且應該改用 -XX:MaxMetaspaceSize=384m。
- 記憶體單位:
- 參數末尾的 m 代表 MB (Megabytes)。
配置範例
Linux 的配置範例
#!/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 上的配置範例
$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 配置
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 的主機來說非常安全。




