【024】JVM 参数入门:堆、栈、元空间与典型模板

线上系统突然变慢,GC 频繁停顿,甚至 OOM 崩溃------这些问题往往和 JVM 参数配置 有关。

很多同学对 JVM 参数的印象是「一堆 -XX: 开头的奇怪配置」,不知道从哪里入手。但其实:

  • 80% 的场景只需要几个核心参数
  • 常见问题可以通过参数调优解决
  • 理解参数能帮你快速定位线上问题

这篇帮你把 JVM 参数彻底搞明白。下面我按「内存参数 → GC 参数 → 诊断参数 → 典型模板」的顺序往下聊。


1. 内存参数:堆、栈、元空间 💾

1.1 堆内存参数

bash 复制代码
# 堆大小
-Xms512m          # 初始堆大小
-Xmx2g            # 最大堆大小
-Xms 和 -Xmx 设成一样,避免运行时动态扩展
bash 复制代码
# 新生代大小
-Xmn256m          # 新生代大小(Eden + Survivor)
-XX:NewRatio=2    # 新生代:老年代 = 1:2(老年代是新生代的 2 倍)
bash 复制代码
# Survivor 区比例
-XX:SurvivorRatio=8  # Eden:Survivor = 8:1(默认)
# 例如:-Xmn512m -XX:SurvivorRatio=8
# 则 Eden = 512m * 8/10 = 409.6m
# 每个 Survivor = 512m * 1/10 = 51.2m

1.2 栈内存参数

bash 复制代码
# 线程栈大小
-Xss1m            # 每个线程的栈大小(默认 1MB)
-Xss512k          # 512KB

常见场景

  • 递归调用深:增大 -Xss
  • 线程数多:减小 -Xss
bash 复制代码
# 查看默认栈大小
java -XX:+PrintFlagsFinal -version | grep ThreadStackSize

1.3 元空间参数

bash 复制代码
# Java 8 及之后
-XX:MetaspaceSize=256m  # 初始元空间大小
-XX:MaxMetaspaceSize=512m  # 最大元空间大小(默认无限制,受物理内存限制)
bash 复制代码
# Java 7 及之前(永久代)
-XX:PermSize=128m  # 初始永久代大小
-XX:MaxPermSize=256m  # 最大永久代大小

1.4 直接内存参数

bash 复制代码
# NIO 直接内存(零拷贝)
-XX:MaxDirectMemorySize=1g  # 直接内存最大 1GB

2. GC 参数:收集器与调优 🧹

2.1 收集器选择

bash 复制代码
# Serial 收集器(单线程)
-XX:+UseSerialGC

# ParNew 收集器(多线程新生代)
-XX:+UseParNewGC

# Parallel 收集器(吞吐量优先)
-XX:+UseParallelGC
-XX:+UseParallelOldGC

# CMS 收集器(低停顿)
-XX:+UseConcMarkSweepGC

# G1 收集器(可预测停顿)
-XX:+UseG1GC

# ZGC 收集器(超低停顿)
-XX:+UseZGC

2.2 CMS 参数

bash 复制代码
# 启用 CMS
-XX:+UseConcMarkSweepGC

# 触发阈值
-XX:CMSInitiatingOccupancyFraction=80  # 老年代使用 80% 时触发 CMS

# 启用并发预清理
-XX:+UseCMSCompactAtFullCollection  # Full GC 时整理碎片
-XX:+UseCMSInitiatingOccupancyOnly  # 只按设定阈值触发

2.3 G1 参数

bash 复制代码
# 启用 G1
-XX:+UseG1GC

# 停顿时间目标
-XX:MaxGCPauseMillis=200  # 目标停顿时间 200ms

# Region 大小
-XX:G1HeapRegionSize=8m  # 每个 Region 大小 8MB

# 触发阈值
-XX:InitiatingHeapOccupancyPercent=45  # 堆使用 45% 时触发并发标记

2.4 GC 日志参数

bash 复制代码
# 打印 GC 详情
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCTimeStamps

# 输出到文件
-Xloggc:gc.log

# 完整配置示例
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log

2.5 GC 线程数

bash 复制代码
# Parallel GC 线程数
-XX:ParallelGCThreads=4

# CMS 并发线程数
-XX:ConcGCThreads=2

3. 调试与诊断参数 🔍

3.1 打印 JVM 信息

bash 复制代码
# 打印所有 JVM 参数
-XX:+PrintFlagsFinal

# 打印命令行参数
-XX:+PrintCommandLineFlags

3.2 OOM 时自动导出堆 dump

bash 复制代码
# OOM 时导出堆 dump
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/heap.hprof

3.3 退出时打印 GC 信息

bash 复制代码
# 程序退出时打印 GC 摘要
-XX:+PrintGCSummary

3.4 远程调试

bash 复制代码
# 启用 JMX
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

4. 典型配置模板 📋

4.1 微服务应用(通用)

bash 复制代码
java -server \
  -Xms512m -Xmx512m \                    # 堆大小
  -Xmn256m \                              # 新生代
  -XX:MetaspaceSize=128m \               # 元空间
  -XX:MaxMetaspaceSize=128m \
  -XX:+UseG1GC \                          # 使用 G1
  -XX:MaxGCPauseMillis=200 \              # 停顿目标
  -XX:+PrintGCDetails \                   # 打印 GC 日志
  -XX:+PrintGCDateStamps \
  -Xloggc:gc.log \
  -jar app.jar

4.2 高并发 API 接口

bash 复制代码
java -server \
  -Xms1g -Xmx1g \                         # 堆大小 1GB
  -Xmn512m \                              # 新生代 512MB
  -XX:MetaspaceSize=256m \
  -XX:MaxMetaspaceSize=256m \
  -XX:+UseG1GC \
  -XX:MaxGCPauseMillis=100 \              # 更短的停顿目标
  -XX:InitiatingHeapOccupancyPercent=45 \
  -XX:+HeapDumpOnOutOfMemoryError \
  -XX:HeapDumpPath=/tmp/oom.hprof \
  -XX:+PrintGCDetails \
  -Xloggc:gc.log \
  -jar api.jar

4.3 后台批处理任务

bash 复制代码
java -server \
  -Xms2g -Xmx2g \                         # 堆大小 2GB
  -Xmn1g \                                # 新生代 1GB
  -XX:MetaspaceSize=256m \
  -XX:MaxMetaspaceSize=256m \
  -XX:+UseParallelGC \                    # 吞吐量优先
  -XX:ParallelGCThreads=8 \
  -XX:+UseParallelOldGC \
  -XX:+PrintGCDetails \
  -Xloggc:gc.log \
  -jar batch.jar

4.4 大内存应用(8GB+)

bash 复制代码
java -server \
  -Xms8g -Xmx8g \                         # 堆大小 8GB
  -Xmn4g \                                # 新生代 4GB
  -XX:MetaspaceSize=512m \
  -XX:MaxMetaspaceSize=512m \
  -XX:+UseG1GC \
  -XX:MaxGCPauseMillis=300 \
  -XX:G1HeapRegionSize=16m \              # 更大的 Region
  -XX:InitiatingHeapOccupancyPercent=40 \
  -XX:+HeapDumpOnOutOfMemoryError \
  -XX:+PrintGCDetails \
  -Xloggc:gc.log \
  -jar large-app.jar

4.5 开发测试环境

bash 复制代码
java -server \
  -Xms256m -Xmx256m \                     # 小堆内存
  -Xmn128m \
  -XX:+UseSerialGC \                      # Serial 收集器足够
  -XX:+PrintGCDetails \
  -Xloggc:gc.log \
  -jar app.jar

5. 参数优先级 📊

5.1 参数分类

优先级 参数类型 示例
内存大小 -Xms, -Xmx, -Xmn
收集器选择 -XX:+UseG1GC
GC 阈值 -XX:MaxGCPauseMillis
日志配置 -XX:+PrintGCDetails
细节调优 -XX:G1HeapRegionSize

5.2 调优顺序

text 复制代码
1. 先设堆大小(-Xms, -Xmx)
2. 选收集器(-XX:+UseG1GC)
3. 设停顿目标(-XX:MaxGCPauseMillis)
4. 开日志(-XX:+PrintGCDetails)
5. 观察后再微调

6. 常见问题与解决 🔧

6.1 OOM:Java heap space

原因:堆内存不足

解决

bash 复制代码
# 增大堆
-Xms2g -Xmx2g

6.2 OOM:Metaspace

原因:元空间不足(类太多)

解决

bash 复制代码
# 增大元空间
-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m

6.3 GC 停顿过长

原因:堆太大、收集器不合适

解决

bash 复制代码
# 1. 减小堆
-Xms1g -Xmx1g

# 2. 换 G1
-XX:+UseG1GC -XX:MaxGCPauseMillis=200

# 3. 减少对象晋升
-XX:MaxTenuringThreshold=5

6.4 线程栈溢出

原因:递归调用太深

解决

bash 复制代码
# 增大栈
-Xss2m

7. 快速参考表 📋

7.1 内存参数

参数 说明 示例
-Xms 初始堆大小 -Xms512m
-Xmx 最大堆大小 -Xmx2g
-Xmn 新生代大小 -Xmn256m
-Xss 线程栈大小 -Xss1m
-XX:MetaspaceSize 元空间初始大小 -XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize 元空间最大大小 -XX:MaxMetaspaceSize=512m

7.2 GC 参数

参数 说明 示例
-XX:+UseSerialGC Serial 收集器 -XX:+UseSerialGC
-XX:+UseParallelGC Parallel 收集器 -XX:+UseParallelGC
-XX:+UseConcMarkSweepGC CMS 收集器 -XX:+UseConcMarkSweepGC
-XX:+UseG1GC G1 收集器 -XX:+UseG1GC
-XX:MaxGCPauseMillis 停顿目标 -XX:MaxGCPauseMillis=200
-XX:ParallelGCThreads GC 线程数 -XX:ParallelGCThreads=4

7.3 诊断参数

参数 说明 示例
-XX:+PrintGCDetails 打印 GC 详情 -XX:+PrintGCDetails
-XX:+HeapDumpOnOutOfMemoryError OOM 时 dump -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath dump 路径 -XX:HeapDumpPath=/tmp/heap.hprof
-Xloggc GC 日志文件 -Xloggc:gc.log

小结

  • 内存参数-Xms/-Xmx(堆)、-Xss(栈)、-XX:MetaspaceSize(元空间)
  • GC 参数 :收集器选择(-XX:+UseG1GC)、停顿目标(-XX:MaxGCPauseMillis
  • 诊断参数 :GC 日志(-XX:+PrintGCDetails)、OOM dump(-XX:+HeapDumpOnOutOfMemoryError
  • 典型模板:微服务用 G1、高并发设停顿目标、批处理用 Parallel
  • 调优顺序:先设堆大小 → 选收集器 → 设目标 → 开日志 → 观察微调

下一篇(025)预告:类加载:双亲委派与应用隔离------类加载器原理、打破双亲委派、Tomcat/Spring 类加载器隔离。

相关推荐
m0_747854521 小时前
CSS如何让响应式图片在容器内居中_利用background-position
jvm·数据库·python
不懒不懒1 小时前
【PaddleOCR实战指南:图像文字识别、实时摄像头与PyQt5 GUI开发】
开发语言·python
han_hanker1 小时前
下拉模糊搜索多选, 编辑,详情问题
开发语言·javascript·ecmascript
2401_871696522 小时前
CSS如何优化移动端CSS选择器性能_遵循BEM规范避免过长嵌套
jvm·数据库·python
invicinble2 小时前
java集合的设计思路
java·开发语言·python
jiayong232 小时前
第 33 课:任务看板视图(按状态分列)与本地持久化
开发语言·前端·javascript·学习
2401_883600252 小时前
Cgo 回调中处理 const char- 参数的正确方法
jvm·数据库·python
A_aspectJ2 小时前
【Java基础开发】 基于Swing GUI 组件实现图书管理系统
java·开发语言
gmaajt2 小时前
CSS 背景图片无法加载的常见原因与正确写法详解
jvm·数据库·python