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

MyCAT Java Heap Space OOM 根因定位與 JVM 參數調優實戰

     編輯:MySQL 綜合教學

MyCAT Java Heap Space OOM 根因定位與 JVM 參數調優實戰

MyCAT 反復出現 java.lang.OutOfMemoryError: Java heap space,卻發現 wrapper.conf 配置了 -Xmx4G。本文實戰演示通過 jmap -heap 穿透真實堆大小,揭示 wrapper.java.initmemory/maxmemory 單位陷阱導致 MaxHeapSize=16MB 的離譜現場,給出生產級 JVM 參數修正方案。

現場還原:兩類 OOM 的區別

錯誤類型堆疊特徵所在內存區典型原因
Java heap spaceTimerXX 線程大量拋出Java Heap堆太小 / 對象洩漏 / 大結果集
Direct buffer memoryBits.reserveMemory / ByteBuffer.allocateDirectDirect Memory (堆外)MaxDirectMemorySize 不足 / Netty 泄漏

關鍵定界:jmap 穿透 wrapper 配置


[root@mycat ~]# jmap -heap $(pgrep -f MycatStartup)
Heap Configuration:
  MinHeapFreeRatio = 0
  MaxHeapFreeRatio = 100
  MaxHeapSize = 16777216 (16.0MB)        <-- 關鍵證據:僅 16MB!
  NewSize = 1310720 (1.25MB)
  MaxNewSize = 17592186044415 MB
  OldSize = 5439488 (5.1875MB)
  ...

根因復盤:wrapper.conf 參數單位陷阱


# wrapper.conf 片段
wrapper.java.additional.10=-Xmx4G
wrapper.java.additional.11=-Xms1G
wrapper.java.initmemory=4G      # 錯誤:單位已固定為 MB,實際生效 4MB
wrapper.java.maxmemory=15G      # 錯誤:實際生效 15MB,且覆蓋 -Xmx

機制: Tanuki Wrapper 解析 wrapper.java.initmemory / maxmemory 時只讀數字,忽略單位後綴,並以 MB 為單位傳給 JVM -Xms/-Xmx。寫 4G → 讀為 4 → -Xms4m -Xmx15m → JVM 向上取整為 16MB。

驗證實驗


# 測試不同值對 MaxHeapSize 影響
wrapper.java.maxmemory=17   -> MaxHeapSize=18MB
wrapper.java.maxmemory=4096  -> MaxHeapSize=4096MB (4GB,觸及 32 位/Wrapper 限制)
wrapper.java.maxmemory=5000  -> MaxHeapSize=4096MB (封頂)

修正方案:棄用 init/maxmemory,專用 additional


# wrapper.conf 修正版
# 刪除或註釋:
# wrapper.java.initmemory=4G
# wrapper.java.maxmemory=15G

# 僅保留標準 JVM 參數(單位自帶,無歧義)
wrapper.java.additional.10=-Xmx4G
wrapper.java.additional.11=-Xms1G
# Direct Memory 另行配置
wrapper.java.additional.12=-XX:MaxDirectMemorySize=10G

啟動腳本雙路徑一致性檢查

MyCAT 提供兩種啟動方式,JVM 參數來源不同,必須保持一致:

啟動方式配置來源關鍵參數位置
bin/mycat startconf/wrapper.confwrapper.java.additional.*
bin/startup_nowrap.sh腳本內 JAVA_OPTS-Xms2G -Xmx2G -XX:MaxDirectMemorySize=2G

建議: 統一使用 wrapper.conf 管理參數,startup_nowrap.sh 僅作調試用,或同步修改兩處。

生產級 JVM 模板(MyCAT 1.6+ / JDK 8)


wrapper.java.additional.1=-server
wrapper.java.additional.2=-Xms4G
wrapper.java.additional.3=-Xmx4G
wrapper.java.additional.4=-XX:NewRatio=2
wrapper.java.additional.5=-XX:SurvivorRatio=8
wrapper.java.additional.6=-XX:MaxDirectMemorySize=8G
wrapper.java.additional.7=-XX:+UseG1GC
wrapper.java.additional.8=-XX:MaxGCPauseMillis=200
wrapper.java.additional.9=-XX:+ParallelRefProcEnabled
wrapper.java.additional.10=-XX:+PrintGCDetails
wrapper.java.additional.11=-XX:+PrintGCDateStamps
wrapper.java.additional.12=-Xloggc:/usr/local/mycat/logs/gc_%p_%t.log
wrapper.java.additional.13=-XX:+UseGCLogFileRotation
wrapper.java.additional.14=-XX:NumberOfGCLogFiles=10
wrapper.java.additional.15=-XX:GCLogFileSize=100M
wrapper.java.additional.16=-XX:+HeapDumpOnOutOfMemoryError
wrapper.java.additional.17=-XX:HeapDumpPath=/usr/local/mycat/logs/heapdump.hprof

監控與告警

  • JMX 導出:-Dcom.sun.management.jmxremote.port=9999 接入 Prometheus JMX Exporter
  • 關鍵指標:jvm_memory_bytes_used{area="heap"} / jvm_memory_bytes_max{area="heap"} > 80% 告警
  • GC 日誌分析:gceasy.io / GCViewer 定期審視 Full GC 頻率與耗時

JVM 參數配置是「一行配置、十行註釋、百行驗證」的嚴謹工程。穿透 Wrapper 層直達 jmap -heap 驗證實際生效值,應成為中間件部署的標準驗收動作。

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