JVM 內存管理是 Java 工程師進階必修課。本文系統講解堆內存結構、GC 觸發機制、四大收集器特性、核心參數調優策略,並給出生產環境常見 OOM 排查思路。
一、JVM 堆內存三大區域
- Young Generation(新生代):新對象誕生地,包含 Eden + 2 個 Survivor 區
- Old Generation(老年代):經過多次 Minor GC 仍存活的對象晉升至此
- Permanent Generation(永久代,JDK 8 移除為 Metaspace):存放類元數據、常量池、方法字節碼
二、核心堆參數
| 參數 | 含義 | 建議值 |
| -Xms | 初始堆大小 | 設為 -Xmx 同值,避免動態擴縮容 |
| -Xmx | 最大堆大小 | 物理內存 60%-80% |
| -Xmn | 新生代大小 | 約 -Xmx 的 1/3 |
| -XX:PermSize / -XX:MaxPermSize | 永久代大小(JDK 7 及之前) | 128M / 256M |
| -XX:MetaspaceSize / -XX:MaxMetaspaceSize | 元空間大小(JDK 8+) | 256M / 512M |
三、為什麼頻繁 Full GC?
- 代碼顯式調用
System.gc() 或中間件自帶 GC
- 堆內存過小(默認值極小)
- 大量短命對象頻繁創建(如循環拼接 String,應用
StringBuilder)
- 內存洩漏:對象被長期引用無法回收
健康指標:每次 GC 後堆剩餘 >50%(服務端建議 >65%)屬正常。
四、棧內存配置
-Xss:每線程棧大小(默認 1M,可調 256K-512K 支持更多線程)
- 棧過大 → 佔用過多內存;過小 → StackOverflowError
五、四大 GC 收集器對比
| 收集器 | 啟動參數 | 特點 | 適用場景 |
| Serial GC | 默認 | 單線程、Stop-the-world | 單 CPU、Client 模式 |
| Parallel GC(吞吐量優先) | -XX:+UseParallelGC | 新生代多線程、老年代單線程 | 多 CPU、批處理、科學計算 |
| CMS(低停頓) | -XX:+UseConcMarkSweepGC | 老年代併發標記清理、碎片整理需 Stop-the-world | 響應敏感、Web 服務 |
| G1(區域化、可預測停頓) | -XX:+UseG1GC (JDK 7u4+) | 混合收集、Region 劃分、可設定目標停頓時間 | 大內存(>4G)、多核、JDK 9+ 默認 |
註:Incremental GC(-Xincgc)已廢棄,不建議使用。
六、硬件層面優化
- 增加物理內存 → 減少 Swap 交換 → GC 效率提升
- 多核 CPU → 並行 GC 線程受益
- SSD 磁盤 → GC 日志寫入、Heap Dump 導出更快
七、生產環境調優清單
# 典型 8G 內存服務器配置示例
-Xms6g -Xmx6g -Xmn2g
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/log/gc.log
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/heapdump.hprof
八、排查工具鏈
jstat -gcutil pid 1000:實時 GC 統計
jmap -histo:live pid:存活對象統計
jmap -dump:live,format=b,file=heap.hprof pid:導出堆快照
MAT (Memory Analyzer Tool):分析堆快照,定位洩漏鏈路
Arthas / Greys:線上診斷神器
- 上一篇文章: Java 正則表達式實戰:中文提取與字符分類
- 下一篇文章: Tapestry 4.1.2 入門教程:組件化 Web 開發初體驗
Copyright ©
程式碼之家 All Rights Reserved