JVM 参数全解析:从基础配置到高级调优
JVM 参数是控制 JVM 运行行为的核心手段,合理配置参数能显著提升应用性能、避免内存溢出等问题。JVM 参数分为标准参数、非标准参数(-X 开头)和非标准化参数(-XX 开头),本文将系统梳理常用参数的分类、作用及配置方式,帮助开发者根据场景选择合适的参数。
JVM 参数类型
标准参数(稳定,跨版本兼容)
以 - 开头,如 java -version、java -classpath 等,本文不重点展开。
非标准参数(-X 开头,半稳定)
由 JVM 实现定义,可能随版本变化,常用参数如下:
| 参数 | 作用描述 |
|---|---|
-Xmixed |
混合模式执行(解释器 + JIT 编译,默认启用) |
-Xint |
仅使用解释器执行(禁用 JIT,适合调试) |
-Xbootclasspath |
设置引导类加载路径(如指定自定义核心类库) |
-Xms<size> |
初始堆内存(等价于 -XX:InitialHeapSize,如 -Xms2g) |
-Xmx<size> |
最大堆内存(等价于 -XX:MaxHeapSize,如 -Xmx4g) |
-Xss<size> |
线程栈大小(等价于 -XX:ThreadStackSize,如 -Xss1m) |
-Xloggc:<file> |
将 GC 日志写入文件(带时间戳,如 -Xloggc:gc.log) |
非标准化参数(-XX 开头,不稳定,最常用)
用于精细控制 JVM 内部行为,分为两类:
- Boolean 类型:
-XX:+<option>(启用)、-XX:-<option>(禁用),如-XX:+PrintGCDetails。 - KV 类型:
-XX:<option>=<value>,如-XX:NewRatio=2。
常用 JVM 参数详解
参数查看与调试
| 参数 | 作用描述 |
|---|---|
-XX:+PrintCommandLineFlags |
程序启动前打印手动或自动设置的 -XX 参数 |
-XX:+PrintFlagsInitial |
打印所有 -XX 参数的默认初始值 |
-XX:+PrintFlagsFinal |
打印运行时生效的 -XX 参数值(最终值) |
-XX:+PrintVMOptions |
仅打印用户设置的 JVM 参数 |
堆内存配置(核心)
堆内存是 JVM 管理的核心区域,参数直接影响 GC 效率和内存利用率:
| 参数 | 作用描述 | 示例 / 默认值 |
|---|---|---|
-Xms / -XX:InitialHeapSize |
初始堆内存(建议与 -Xmx 相同,避免动态调整) |
-Xms2g(初始堆 2GB) |
-Xmx / -XX:MaxHeapSize |
最大堆内存(根据物理内存设置,如服务器建议设为物理内存的 1/2 ~ 1/3) | -Xmx4g(最大堆 4GB) |
-Xmn / -XX:NewSize + -XX:MaxNewSize |
新生代大小(初始值 + 最大值,建议为堆大小的 1/3 ~ 1/2) | -Xmn1g(新生代 1GB) |
-XX:NewRatio |
老年代与新生代的比例(老年代 = 新生代 × NewRatio) |
默认 2(老:新 = 2:1) |
-XX:SurvivorRatio |
新生代中 Eden 与单个 Survivor 区的比例(Eden = Survivor × SurvivorRatio) |
默认 8(Eden:From:To = 8:1:1) |
-XX:MaxTenuringThreshold |
新生代对象晋升老年代的最大年龄(每经历一次 Minor GC 年龄 +1) | 默认 15(JDK8) |
-XX:PretenureSizeThreshold |
大对象直接分配到老年代的阈值(仅对 Serial/ParNew 有效) | 默认 0(所有对象先入新生代) |
栈与方法区配置
| 参数 | 作用描述 | 示例 / 默认值 |
|---|---|---|
-Xss / -XX:ThreadStackSize |
单个线程的栈大小(影响线程数量,过大会减少线程数) | -Xss1m(每个线程栈 1MB) |
-XX:MetaspaceSize |
元空间(方法区)初始大小(JDK8+,替代永久代 PermSize) |
默认约 21MB |
-XX:MaxMetaspaceSize |
元空间最大大小(默认无限制,建议设上限避免耗尽系统内存) | -XX:MaxMetaspaceSize=256m |
-XX:CompressedClassSpaceSize |
压缩类空间大小(元空间的一部分,存储类元数据) | 默认 1GB |
直接内存配置
直接内存(堆外内存)用于 NIO 操作,需单独控制:
| 参数 | 作用描述 | 示例 / 默认值 |
|---|---|---|
-XX:MaxDirectMemorySize |
直接内存最大容量(默认与堆最大值相同) | -XX:MaxDirectMemorySize=1g |
垃圾收集器配置
不同收集器适用于不同场景(如低延迟、高吞吐量),需通过参数指定:
| 收集器类型 | 启用参数 | 核心配置参数 |
|---|---|---|
| Serial | -XX:+UseSerialGC |
新生代 Serial + 老年代 Serial Old(单线程,适合小堆) |
| ParNew | -XX:+UseParNewGC |
新生代 ParNew(多线程) + 老年代 Serial Old(需配合 -XX:ParallelGCThreads 设线程数) |
| Parallel | -XX:+UseParallelGC |
新生代 Parallel Scavenge + 老年代 Parallel Old(吞吐量优先,JDK8 默认) |
| CMS | -XX:+UseConcMarkSweepGC |
老年代 CMS(低延迟,需配合 -XX:CMSInitiatingOccupancyFraction=70 设触发阈值) |
| G1 | -XX:+UseG1GC |
区域化分代收集器(大堆友好,需配合 -XX:MaxGCPauseMillis=200 设目标停顿时间) |
| ZGC/Shenandoah | -XX:+UseZGC / -XX:+UseShenandoahGC |
低延迟收集器(JDK11+,适合超大堆) |
GC 日志配置
GC 日志是分析 GC 问题的关键,建议生产环境开启:
| 参数 | 作用描述 | 示例 |
|---|---|---|
-XX:+PrintGC |
打印简化 GC 日志(等价于 -verbose:gc) |
|
-XX:+PrintGCDetails |
打印详细 GC 日志(包括分代内存变化) | |
-XX:+PrintGCDateStamps |
日志中添加日期时间戳(如 2023-10-01T12:00:00.123+0800) |
|
-Xloggc:<file> |
指定 GC 日志文件路径 | -Xloggc:/var/log/gc.log |
-XX:+UseGCLogFileRotation |
开启日志滚动(避免单文件过大) | 需配合 -XX:GCLogFileSize 和 -XX:NumberOfGCLogFiles |
-XX:GCLogFileSize=<size> |
单个日志文件大小(滚动触发阈值) | -XX:GCLogFileSize=100m |
-XX:NumberOfGCLogFiles=<n> |
最大日志文件数(超过后覆盖旧文件) | -XX:NumberOfGCLogFiles=10 |
OOM 与内存快照配置
| 参数 | 作用描述 | 示例 |
|---|---|---|
-XX:+HeapDumpOnOutOfMemoryError |
OOM 时自动生成堆快照(hprof 文件) |
-XX:HeapDumpPath=/tmp/oom.hprof |
-XX:+HeapDumpBeforeFullGC |
Full GC 前生成堆快照(用于分析 GC 原因) | |
-XX:OnOutOfMemoryError=<cmd> |
OOM 时执行指定命令(如重启应用) | -XX:OnOutOfMemoryError="sh restart.sh" |
其他实用参数
| 参数 | 作用描述 | 示例 / 默认值 |
|---|---|---|
-XX:+DisableExplicitGC |
禁用 System.gc()(避免手动触发 Full GC) |
默认禁用(-XX:-DisableExplicitGC) |
-XX:+DoEscapeAnalysis |
开启逃逸分析(允许栈上分配,减少堆内存使用) | 默认开启(JDK6u23+) |
-XX:+UseTLAB |
启用线程本地分配缓冲(TLAB,减少并发分配冲突) | 默认开启 |
-XX:TLABWasteTargetPercent |
TLAB 占 Eden 区的比例(默认 1%) | -XX:TLABWasteTargetPercent=5 |
-XX:+PrintClassHistogram |
程序退出时打印类实例统计(类名、实例数、内存占比) |
参数配置最佳实践
堆内存设置:
- 生产环境建议
-Xms与-Xmx相等(如-Xms4g -Xmx4g),避免动态调整开销。 - 新生代大小建议为堆的 1/3 ~ 1/2(如堆 4GB 时,新生代设为 1.5GB)。
- 生产环境建议
收集器选择:
- 低延迟场景(如 Web 服务):G1 或 ZGC(
-XX:+UseG1GC)。 - 高吞吐量场景(如批处理):Parallel GC(JDK8 默认,
-XX:+UseParallelGC)。
- 低延迟场景(如 Web 服务):G1 或 ZGC(
日志配置:
生产环境务必开启详细 GC 日志,便于排查问题:1
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/log/app/gc.log -XX:+UseGCLogFileRotation -XX:GCLogFileSize=100m -XX:NumberOfGCLogFiles=10
OOM 防护:
开启自动堆快照,便于事后分析:1
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/app/oom.hprof
v1.3.10