常见的 JVM 调优参数有哪些(如 -Xms, -Xmx 等)?
JVM 调优参数非常多,通常可以分为以下几大类:堆内存设置、非堆内存设置、垃圾回收器(GC)选择、GC 日志与排查。
以下是开发和运维中最常用的 JVM 参数详解:
1. 堆内存相关 (Heap Memory)
这是最基础也是最重要的调整部分,直接影响 OOM(内存溢出)和 GC 频率。
-Xms(Initial Heap Size)- 含义:JVM 启动时的初始堆内存大小。
- 建议:通常设置为与
-Xmx相同,以避免 JVM 在运行过程中因为动态扩容和缩容堆内存而产生额外的性能开销。 - 示例:
-Xms4g
-Xmx(Maximum Heap Size)- 含义:JVM 允许申请的最大堆内存大小。
- 建议:不要超过物理内存的 70%-80%,给操作系统和其他进程留足空间。
- 示例:
-Xmx4g
-Xmn(New Generation Size)- 含义:设置新生代(Young Gen)的大小。
- 影响:设置过小会导致频繁 Minor GC;设置过大会导致老年代变小,引发 Full GC。
- 建议:通常设置为堆总大小的 1/3 到 1/4。推荐使用 G1 收集器时不要手动设置此值,让 G1 自动调整。
- 示例:
-Xmn1g
-XX:SurvivorRatio- 含义:新生代中 Eden 区与 Survivor 区(S0/S1)的大小比例。
- 默认:8(即 Eden:S0:S1 = 8:1:1)。
- 场景:如果对象生命周期很短,可以增大该值以增加 Eden 区空间。
2. 非堆内存与线程栈 (Non-Heap & Stack)
-XX:MetaspaceSize(Java 8+)- 含义:元空间(Metaspace)的初始阈值(高水位线)。一旦达到这个值,会触发 Full GC 来调整元空间大小。
- 注意:这不是初始大小,而是触发 GC 的阈值。
-XX:MaxMetaspaceSize(Java 8+)- 含义:元空间的最大允许大小。
- 建议:务必设置。如果不设置,元空间会默认使用宿主机的物理内存,一旦发生内存泄漏,可能导致整个服务器卡死。
- 示例:
-XX:MaxMetaspaceSize=256m
-Xss(Thread Stack Size)- 含义:每个线程的栈内存大小。
- 影响:决定了方法调用的深度(递归深度)和可创建的线程数量。
- 建议:默认通常是 1M。如果线程数非常多(如高并发应用),可以适当调小(如 256k)以节省内存;如果出现
StackOverflowError,则需调大。 - 示例:
-Xss256k
-XX:MaxDirectMemorySize- 含义:最大堆外内存(Direct Memory)大小,常用于 NIO 框架(如 Netty)。
- 建议:如果不设置,默认与
-Xmx大小一致。使用 Netty 等框架时需关注。
3. 垃圾回收器选择 (GC Collector)
根据业务场景(吞吐量优先 vs 延迟优先)选择合适的 GC。
-XX:+UseSerialGC- 含义:使用串行收集器。
- 场景:单核 CPU、小内存应用(Client 模式)。
-XX:+UseParallelGC(JDK 8 默认)- 含义:使用并行收集器(关注吞吐量)。
- 场景:后台计算任务、报表生成等不需要实时响应的系统。
-XX:+UseConcMarkSweepGC(CMS)- 含义:使用 CMS 收集器(关注低延迟)。
- 现状:JDK 9 标记废弃,JDK 14 删除。老系统常用。
-XX:+UseG1GC(JDK 9+ 默认)- 含义:使用 G1 收集器(兼顾吞吐量和低延迟,大堆内存首选)。
- 场景:目前大多数服务端应用的主流选择(尤其是堆内存 > 4G 时)。
-XX:+UseZGC(JDK 11/15+)- 含义:使用 ZGC(超低延迟,停顿时间 < 10ms)。
- 场景:超大堆内存(TB 级)、对延迟极其敏感的系统。
4. 故障排查与日志 (Diagnostics & Logging)
这些参数在生产环境中强烈建议开启,用于事后分析。
-XX:+HeapDumpOnOutOfMemoryError- 含义:当发生 OOM(内存溢出)时,自动生成堆内存快照(Dump 文件)。
- 作用:事后分析 OOM 原因的神器。
-XX:HeapDumpPath=<path>- 含义:指定 Dump 文件的生成路径。
- 示例:
-XX:HeapDumpPath=/var/logs/jvm/heapdump.hprof
GC 日志参数:
- JDK 8 及之前:
-XX:+PrintGCDetails:打印详细 GC 日志。-XX:+PrintGCDateStamps:打印 GC 发生的时间戳。-Xloggc:<file>:指定 GC 日志输出文件。
- JDK 9 及之后(统一日志框架):
-Xlog:gc*:file=<file>:例如-Xlog:gc*:file=/var/log/gc.log:time,tags
- JDK 8 及之前:
5. 一个典型的生产环境配置示例 (JDK 8, 4G 堆)
bash
java -server \
-Xms4g \
-Xmx4g \
-Xmn2g \
-Xss256k \
-XX:MetaspaceSize=256m \
-XX:MaxMetaspaceSize=256m \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/logs/heapdump.hprof \
-jar app.jar
总结与建议
-Xms和-Xmx设置成一样,防止内存抖动。-XX:MaxMetaspaceSize必须设置,防止元空间撑爆物理内存。- JDK 8 以上首选 G1 收集器。
- 不要盲目调优:JVM 默认配置在大多数情况下已经足够好。只有在监控发现 GC 频繁、停顿时间过长或出现 OOM 时,才需要针对性调整。
右滑查看面试常问