JVM系列-JVM参数手册

有时候找到了一个JVM参数,以为找到了一份武林秘籍,就偷偷在服务器把参数加上,结果第二天就收获一个事故通报。

本文对常用 JVM 常用参数做了一个整理,但是参数的使用很复杂,本文仅仅提供常用参数的查阅,具体的使用还是需要根据具体的情况。

JVM 是一个开放的标准,谁可以来实现 JVM,这导致不同JVM 实现的参数有所不同,本文基于 Hotspot 虚拟机。

JVM 参数很多,总体上可以分成三类:

  • -:标准参数,比如 -verbose:gc 这类表示标准实现,所有的虚拟机都需要实现这些参数的功能,且向后兼容
  • -X:非标准参数,默认 JVM 会实现这些参数的功能,但是不保证所有的 JVM 实现都满足,且不保证向后兼容
  • -XX:非 Stable 参数,这些参数在不同的 JVM 上会有不同的实现,这些参数不推荐在生成环境中使用,以后很有可能会被取消
    • 对于布尔型参数:-XX:+ 表示打开,-XX:- 表示关闭,比如: -XX:+PrintGCDetails
    • 对于其他的数字或者字符参数:-XX: 表示设定一个值

通用参数

JDK8 JDk9 Or Later 备注
-verbose:class -verbose:class 输出 jvm 载入类的相关信息, 可用于排查找不到类或者类冲突问题
-verbose:gc -verbose:gc 输出 GC 信息,当日志被保存为文件时,这个参数无效
-verbose:jni -verbose:jni 输出 native 方法的调用情况,用于排查 JNI 调用问题
-Xms -Xms 初始堆大小,默认物理内存的 1/64
-Xmx -Xmx 最大堆大小,默认为物理内存的 1/4
-Xmn -Xmn 新生代大小
-Xss -Xss 堆栈大小,JDK5 以后,每个线程的对接默认为 1 M
-Xnoclassgc -Xnoclassgc 关闭对类的回收
-XX:MaxMetaspaceSize -XX:MaxMetaspaceSize 元空间的最大值
-XX:MetaspaceSize -XX:MetaspaceSize 指定元空间触发 Full GC 的阈值,也就是默认元空间的大小
-XX:SurvivorRatio -XX:SurvivorRatio 新生代中 Eden 与 Survivor 的比值,默认为 8,Survivor 有两块空间, from 和 to,实际上,Eden 与 Survivor 的比值大小为 8 : 2
-XX:NewRatio -XX:NewRatio 新生代和老年代空间的比值
-XX:LargePageSizeInBytes -XX:LargePageSizeInBytes 设置用于Java堆的大页面尺寸
-XX:+UseLargePages -XX:+UseLargePages 使用大页面内存
-XX:MaxHeapFreeRatio -XX:MaxHeapFreeRatio GC后java堆中空闲量空间的最大占比
-XX:MinHeapFreeRatio -XX:MinHeapFreeRatio GC后java堆中空闲量空间的最小占比
-XX:NewSize -XX:NewSize 新生代对象生成时占用内存的默认值
-XX:MaxNewSize -XX:MaxNewSize 新生成对象能占用内存的最大值
-XX:MaxPermSize -XX:MaxPermSize 老生代对象能占用内存的最大值
-XX:ThreadStackSize -XX:ThreadStackSize 设置线程栈大小,若为0则使用系统默认值

GC 参数

在 JDK9 以后,日志相关的参数的都统一到了 -Xlog 中,注意,不仅仅 gc 的日志,是所有的日志,对于 -Xlog,配置方法如下:

1
-Xlog[:[selector][:output[:[decorators][:output-options]]]]

其中 selector 是 tag 和日志 level 的组合体,tag 就是日志类别,gc 只是其中的一种 tag,如果要输出 GC 日志,使用方式如下:

1
-Xlog:gc

level 的取值有:off,trace,debug,info,warning,error。

output 就是日志的输出形式,可以使用的方式有:

  • stdout
  • stderr
  • file=

decorators 称之为装饰器,可以在 GC 日志中增加其他的信息,方便对问题进行定位,装饰器可以同时使用多个,下面是对装饰器的汇总:

全名 缩写 备注
hostname hn 机器名称
level l 日志等级
pid p 进程标识符
tid ti 线程标识符
tags tg 与消息相关联的所有标签
time t 当前时间和日期为ISO-8601格式(例如:2020-07-31T18:42:58.418 + 0000)
timemillis tm 当前时间以毫秒为单位,与System.currentTimeMillis()生成的值相同
timenanos tn 当前时间以纳秒为单位,与System.nanoTime()生成的值相同
uptime u 自JVM启动以来运行的时间,以秒为单位
uptimemillis um 自JVM启动以来运行的毫秒数
uptimenanos un 自JVM启动以来运行的纳秒数
utctime utc 当前时间和日期,UTC 格式,例如:2020-07-31T12:42:58.418-0600)

在默认情况下,会使用 uptime,level 以及 tags 等装饰器,也可以使用 none 来关闭所有的装饰器。

假如说现在要获取日志等级为info,需要打印机器名称、日志等级,JVM 的运行时间,所属 tag,并且要把这些日志保存为 gc.log 文件,配置如下:

1
-Xlog:gc*=info:file=gc.log:hostname,level,uptime,tags

常用的 GC 日志参数如下:

GC日志参数

JDK8 JDk9 Or Later 备注
-XX:+PrintGC -Xlog:gc 打印 GC 信息
-XX:+PrintGCDeatils -Xlog:gc* 打印 GC 详细信息
-XX:+PrintGCTimeStamps uptime 装饰器 打印 GC 过程中具体的时间戳
-XX:+PrintHeapAtGC -Xlog:gc+heap=trace 打印 GC 前后堆的详细信息
-XX:+PrintGCApplicationStoppedTime -Xlog:safepoint 打印 GC 期间程序暂停的时间
-XX:+PrintGCApplicationConcurrentTime -Xlog:safepoint 打印 GC 前,程序未中断的执行时间
-Xloggc:filename -Xlog:gc:file=gc.log GC 日志的保存为文件,默认为项目根目录
-XX:+PrintTenuringDistribution -Xlog:gc+age*=trace 查看对象存在于新生代所经历 Minor GC 次数的阈值
-XX:PrintReferenceGC -Xlog:gc+ref*=debug 打印软引用、弱引用、虚引用和Finallize队列
-XX:+PrintTLAB -XX:+PrintTLAB 打印 TLAB 信息

其他GC参数

JDK8 JDk9 Or Later 备注
-XX:MaxTenuringThreshold -XX:MaxTenuringThreshold 对象存在于新生代所能经历 Minor GC 的最大次数
-XX:PretenureSizeThreshold -XX:PretenureSizeThreshold 超出该大小的对象直接在老年代分配,单位字节
-XX:+UseSerialGC -XX:+UseSerialGC 使用 serial 和 serial old 收集器(client VM 的默认值)
-XX:+UseParallelGC -XX:+UseParallelGC 使用 parallel 和 parallel old 收集器(serverVM 的默认值)
-XX:+UseConcMarkSweepGC -XX:+UseConcMarkSweepGC 使用 ParNew 和 CMS 收集器
-XX:+UseParNewGC -XX:+UseParNewGC 使用 ParNew 和 serial old 收集器(已不推荐)
-XX:ParallelGCThreads -XX:ParallelGCThreads 并行收集的线程数,最好与 CPU 数量相同
-XX:GCTimeRatio -XX:GCTimeRatio 设置并行收集器的吞吐量,如 99 表示 1 /(1+99) = 1 %,表示 GC 只能占用 1 % 的时间,满足不了则会缩小 新生代空间
-XX:MaxGCPauseMillis -XX:MaxGCPauseMillis 每次年轻代垃圾回收的最长时间
-XX:CMSFullGCsBeforeCompaction -XX:CMSFullGCsBeforeCompaction 设置在 n 次 CMS 垃圾收集后,触发一次内存整理
-XX:UseCMSCompactAtFullCollection -XX:UseCMSCompactAtFullCollection 每次 FullGC 后都会触发内存整理
-XX:CMSInitiatingOccupancyFraction -XX:CMSInitiatingOccupancyFraction 触发CMS收集的内存比例
-XX:+DisableExplicitGC -XX:+DisableExplicitGC 禁用 System.gc()
-XX:+CollectGen0First -XX:+CollectGen0First Full GC 前是否先进行 YGC

REF

[1] https://openjdk.java.net/jeps/158

[2] https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE

[3] https://www.oracle.com/java/technologies/javase/vmoptions-jsp.html

[4] https://segmentfault.com/a/1190000013475524

文 / Rayjun

© 2020 Rayjun    PowerBy Hexo