高 进阶
JVM常用调优参数#
一句话答案#
核心参数:-Xms/-Xmx(堆大小)、-XX:+UseG1GC(收集器)、-XX:MaxGCPauseMillis(目标停顿)、-XX:+HeapDumpOnOOM。
核心要点
内存相关:
| 参数 | 作用 | 说明 |
|---|---|---|
-Xms / -Xmx | 堆初始 / 最大值 | 生产常设成一样,避免堆伸缩 |
-Xmn 或 -XX:NewRatio | 新生代大小 / 老年代与新生代比例 | 用 G1 时一般不手动设,交给停顿目标自适应 |
-Xss | 每个线程栈大小 | Linux x64 默认 1MB |
-XX:MetaspaceSize / -XX:MaxMetaspaceSize | 元空间首次触发 GC 的阈值 / 上限 | 上限默认不限制 |
-XX:MaxDirectMemorySize | 直接内存上限 | 不设时约等于 -Xmx |
-XX:MaxRAMPercentage | 堆占可用内存(容器限制)的百分比 | 容器环境替代硬编码 -Xmx |
GC 相关:
| 参数 | 作用 |
|---|---|
-XX:+UseG1GC / -XX:+UseZGC / -XX:+UseParallelGC | 选择收集器(JDK 9+ 默认 G1) |
-XX:MaxGCPauseMillis=200 | G1 目标停顿时间(默认 200ms,是软目标) |
-XX:InitiatingHeapOccupancyPercent=45 | G1 并发标记触发阈值(默认 45%) |
-XX:G1HeapRegionSize | G1 Region 大小(2 的幂,默认按堆大小自动计算) |
诊断相关:
| 参数 | 作用 |
|---|---|
-XX:+HeapDumpOnOutOfMemoryError + -XX:HeapDumpPath | OOM 时自动导出堆快照 |
-Xlog:gc*:file=gc.log:time,uptime | JDK 9+ 统一日志输出 GC 日志 |
-Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps | JDK 8 的 GC 日志写法(JDK 9+ 已被 -Xlog 取代) |
-XX:NativeMemoryTracking=summary | 开启堆外内存追踪,配合 jcmd VM.native_memory |
调优思路: 先定目标(吞吐 / 延迟 / 内存占用)→ 用 GC 日志和监控找瓶颈 → 一次只改一个参数 → 压测验证。
面试回答(2分钟版)
JVM 调优参数我按内存、GC、诊断三个维度来说。内存方面,-Xms 和 -Xmx 设置堆的初始和最大值,建议设成一样避免运行时堆动态伸缩带来的性能开销;-XX:MetaspaceSize 和 MaxMetaspaceSize 控制元空间大小,动态代理或大量类加载的应用需要适当调大。GC 方面,-XX:+UseG1GC 选择 G1 收集器,配合 -XX:MaxGCPauseMillis 设置目标停顿时间,G1 会自动调整 Region 回收策略来尽量满足目标。诊断方面,-XX:+HeapDumpOnOutOfMemoryError 是必配参数,OOM 时自动导出堆快照保留现场;GC 日志在 JDK 8 用 -Xloggc,JDK 9 之后用统一日志 -Xlog:gc* 开启,用于事后分析。实际调优要结合业务场景和压测数据,不能照搬网上配置。
追问与易错
追问方向:
- “-Xms 和 -Xmx 为什么建议设成一样?”→ 避免 JVM 运行时动态伸缩堆大小带来的性能开销和 GC 停顿,预分配固定内存减少内存申请和释放的系统调用
- “怎么选择 GC 收集器?”→ 吞吐优先选 Parallel GC,低延迟选 G1(堆 > 4GB)或 ZGC(超大堆),JDK8 默认 Parallel,JDK9+ 默认 G1;小堆 + 单核可用 Serial
- “你在生产环境设过哪些 JVM 参数?”→ 经验题,常见组合:-Xms/-Xmx 设相同值、-XX:+UseG1GC、-XX:MaxGCPauseMillis=200、-XX:+HeapDumpOnOutOfMemoryError、GC 日志(JDK 8 用 -Xloggc,JDK 9+ 用 -Xlog:gc*)、-XX:MetaspaceSize 调大防频繁 Full GC
易错点:
- ❌ 照搬网上参数不结合实际场景
- ❌ 忘记设 HeapDumpOnOOM