基于本文回答
0
评论

常见的 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

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

总结与建议

  1. -Xms-Xmx 设置成一样,防止内存抖动。
  2. -XX:MaxMetaspaceSize 必须设置,防止元空间撑爆物理内存。
  3. JDK 8 以上首选 G1 收集器
  4. 不要盲目调优:JVM 默认配置在大多数情况下已经足够好。只有在监控发现 GC 频繁、停顿时间过长或出现 OOM 时,才需要针对性调整。
右滑查看面试常问