JVM性能监控调优工具
JDK 自带工具
本地环境安装过完整 JDK 包之后,会在 $JAVA_HOME/bin
目录下发现很多工具,包括编译命令 javac
、执行命令 java
等。本节我们梳理一下其中用于 JVM 运维的工具。
jps
jps (Java Virtual Machine Process Status Tool)
jps 是 JVM 进程查找工具,类似于 linux 的 ps
命令。我们使用这个命令主要是为了找到当前正在运行的 JVM 及其进程 ID。。语法格式如下:
1 | jps [options] [hostid] |
如果不指定 hostid 就默认为当前主机或服务器。
命令行参数选项说明如下:
1 | -q 不输出类名、Jar名和传入main方法的参数 |
jstat
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html
jstat 是 JDK 自带的一个轻量级小工具。全称“Java Virtual Machine statistics monitoring tool”,主要利用 JVM 内建的指令对 Java 应用程序的资源和性能进行实时的命令行的监控,包括了对 Heap size 和垃圾回收状况的监控。
下面展示常用命令 jstat -<option> <pid> [<interval> [<count>]]
<pid>
: Java 进程的进程 ID。<interval>
: 采样的时间间隔(以毫秒为单位)。如果不提供此参数,默认为 1000 毫秒(1 秒)。<count>
: 采样的次数。如果不提供此参数,默认将一直进行采样,直到命令被手动终止。
option | 说明 |
---|---|
-class | 显示加载 class 的数量,及所占空间等信息 |
-compiler | 显示 VM 实时编译的数量等信息 |
-gc | 可以显示 gc 的信息,查看 gc 的次数,及时间 |
-gccapacity | 查看内存中堆的分代内存大小 |
gccause | 显示有关垃圾收集统计信息的摘要 |
-gcnew | 年轻代对象的信息 |
-gcnewcapacity | 年轻代空间大小统计 |
-gcold | 年老代空间大小统计 |
-gcoldcapacity | 年老代容量空间大小统计 |
-gcmetacapacity | 元数据空间统计 |
-gcutil | 垃圾收集统计信息摘要 |
-printcompilation | Java HotSpot 虚拟机 编译方法统计 |
–class
1 | c: \Users\dev>jstat-class13380 Loaded Bytes Unloaded Bytes Time 18051 32345.3 0 0 |
-compiler
1 | C:\Users\dev>jstat -compiler 13380 |
-gc
1 | 例子如下 |
列名 | 描述 |
---|---|
S0C | 幸存区 Survior1 S0 空间容量 (kb) |
S1C | 幸存区 Survior S1 空间容量(kb) |
S0U | 幸存区 Survior1 S0 使用空间(kb) |
S1U | 幸存区 Survior S1 使用空间(kb) |
EC | Eden 区空间容量(kb) |
EU | Eden 区使用空间(kb) |
OC | 老年代 Old 空间容量(kb) |
OU | 老年代 Old(kb) |
MC | 元空间 MetaSpace 空间容量(kb) |
MU | 元空间 MetaSpace 使用空间(kb) |
CCSC | 压缩类空间容量(kb) |
CCSU | 压缩类使用空间(kb) |
YGC | 年轻代 gc 回收数量 |
YGCT | 年轻代 gc 收集时间 |
FGC | full gc 执行数量 |
FGCT | full gc 执行总时间 |
GCT | 总垃圾回收时间 |
-gccapacity
1 | 查看内存中堆的分代内存大小 |
列名 | 描述 |
---|---|
NGCMN | Young 年轻代最小的新一代容量(kB) |
NGCMX | Young 年轻代最大新一代容量(kB) |
NGC | Young 年轻代 当前容量(kB) |
S0C | 幸存区 Survior S0 空间容量 (kB) |
S1C | 幸存区 Survior S1 空间容量 (kB) |
EC | Eden 区空间容量(kB) |
OGCMN | Old 老年代最小的新一代容量(kB) |
OGCMX | Old 老年代最大新一代容量(kB) |
OGC | 当前 Old 老年代容量(kB) |
OC | 当前旧的 Old 老年代容量(kB) |
MCMN | 最小 Metaspace 元空间容量(kB) |
MCMX | 最大 Metaspace 元空间容量(kB) |
MC | Metaspace 元空间容量(kB) |
CCSMN | 压缩类最小空间(kB) |
CCSMX | 压缩类最大空间(kB) |
CCSC | 压缩类的空间(kB) |
YGC | 年轻代 GC 事件的数量 |
FGC | Full GC 事件的数量 |
-gccause
1 | 显示有关垃圾收集统计信息的摘要 |
列名 | 描述 |
---|---|
S0 | 幸存区 Survior S0 利用率占空间当前容量的百分比 |
S1 | 幸存区 Survior S1 利用率占空间当前容量的百分比 |
E | Eden 区利用率占空间当前容量的百分比 |
O | Old 老年代利用率占空间当前容量的百分比 |
M | Metaspace 元空间利用率占空间当前容量的百分比 |
CCS | 以百分比形式压缩的类空间利用率 |
YGC | 年轻代 GC 事件的数量 |
YGCT | 年轻代垃圾回收时间 |
FGCT | 老年代 GC 时间 |
GCT | 总垃圾回收时间 |
LGCC | 上次垃圾回收的原因 |
GCC | 当前垃圾回收的原因 |
-gcnew
1 | 年轻代对象的信息 |
列名 | 描述 |
---|---|
S0C | 幸存区 Survior S0 空间容量 (kb) |
S1C | 幸存区 Survior S1 空间容量(kb) |
S0U | 幸存区 Survior1 S0 使用空间(kb) |
S1U | 幸存区 Survior S1 使用空间(kb) |
TT | 年轻代晋升到年老代的阈值 |
MTT | 年轻代晋升到年老代最大阈值 |
DSS | 所需的 Survior1 幸存者大小 |
EC | Eden 区空间容量(kb) |
EU | Eden 区使用空间(kb) |
YGC | 年轻代 gc 回收数量 |
YGCT | 年轻代 gc 收集时间 |
-gcnewcapacity
1 | 年轻代空间大小统计 |
列名 | 描述 |
---|---|
NGCMN | Young 年轻代最小的新一代容量(kB) |
NGCMX | Young 年轻代最大新一代容量(kB) |
NGC | Young 年轻代 当前容量(kB) |
S0CMX | 幸存区 Survior S0 最大容量(kB) |
S0c | 存区 Survior S0 空间容量 (kb) |
S1CMX | 幸存区 Survior S1 最大容量(kB) |
S1C | 存区 Survior S1 空间容量 (kb) |
ECMX | Eden 区空间最大容量(kb) |
EC | Eden 区空间容量(kb) |
YGC | 年轻代 gc 回收数量 |
FGC | Full gc 执行回收数量 |
-gcold
1 | 年老代空间大小统计 |
列名 | 描述 |
---|---|
MC | Metaspace 元空间容量(kB) |
MU | 元空间 MetaSpace 使用空间(kb) |
CCSC | 压缩类的空间(kB) |
CCSU | 压缩类使用空间(kb) |
OC | 老年代 Old 空间容量(kb) |
OU | 老年代 Old(kb) |
YGC | 年轻代 gc 回收数量 |
FGC | Full gc 执行回收数量 |
FGCT | 老年代 GC 时间 |
GCT | 总垃圾回收时间 |
-gcoldcapacity
1 | 年老代容量空间大小统计 |
列名 | 描述 |
---|---|
OGCMN | Old 年老代最小容量(kb) |
OGCMX | Old 年老代最大容量(kb) |
OGC | 当前 Old 老年代容量(kB) |
OC | 当前旧的 Old 老年代容量(kB) |
YGC | 年轻代 gc 回收数量 |
FGC | Full gc 执行回收数量 |
FGCT | 老年代 GC 时间 |
GCT | 总垃圾回收时间 |
-gcmetacapacity
1 | 元数据空间统计 |
列名 | 描述 |
---|---|
MCMN | 最小 Metaspace 元空间容量(kB) |
MCMX | 最大 Metaspace 元空间容量(kB) |
MC | Metaspace 元空间容量(kB) |
CCSMN | 压缩类最小空间(kB) |
CCSMX | 压缩类最大空间(kB) |
CCSC | 压缩类空间容量(kb) |
CCSU | 压缩类使用空间(kb) |
YGC | 年轻代 gc 回收数量 |
FGC | Full gc 执行回收数量 |
FGCT | 老年代 GC 时间 |
GCT | 总垃圾回收时间 |
gcutil
1 | 垃圾收集统计信息摘要 |
列名 | 描述 |
---|---|
S0 | 幸存区 Survior S0 利用率占空间当前容量的百分比 |
S1 | 幸存区 Survior S1 利用率占空间当前容量的百分比 |
E | Eden 区利用率占空间当前容量的百分比 |
O | Old 老年代利用率占空间当前容量的百分比 |
M | Metaspace 元空间利用率占空间当前容量的百分比 |
CCS | 以百分比形式压缩的类空间利用率 |
YGC | 年轻代 GC 事件的数量 |
YGCT | 年轻代垃圾回收时间 |
FGCT | 老年代 GC 时间 |
GCT | 总垃圾回收时间 |
1 |
-printcompilation
1 | Java HotSpot 虚拟机 编译方法统计 |
列名 | 描述 |
---|---|
Compiled | 最近编译的方法执行的编译任务数 |
Size | 最近编译的方法的字节码的字节数 |
Type | 最近编译的方法的编译类型 |
Method | 标识最近编译的方法的类名和方法名 |
jstack
jstack 用于生成虚拟机当前时刻的线程快照。生成线程快照主要是为了定位长时间停顿的线程,比如线程间死锁、死循环、请求外部资源超时等等。通过 jstack 可以查看到各个线程的调用堆栈信息,就可以知道线程目前运行在哪一句代码,在做什么事情或者等待什么资源。
同样的,jstack 使用时,也要注意用户、版本是否与目标 JVM 一致。
1 | jstack [option] pid |
命令行参数选项说明如下:
1 | -F :强制输出线程堆栈 |
jstack 可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在 JVM 性能调优中使用得非常多。
jmap
jmap 是 java 内存映像工具,主要用于查询当前堆和方法区的详细信息,生成堆的快照文件等。一般都是使用 -XX:+HeapDumpOnOutOfMemoryError
参数指定 JVM 在内存溢出异常时自动生成堆的快照文件。之后在服务器发生内存溢出异常时,将对应的快照文件拉取到本地使用工具分析。
常用的 options 参数:
1 | -heap 显示 Java 堆详细信息 |
jmap 的堆转储快照文件有很多工具可以分析,常用的有 MAT,Jprofiler,IBM HeapAnalyzer 等,后续章节会一一介绍。
可以使用 jmap -histo[:live] <pid>
分析当前堆中对象,例如 ./jmap -histo:live 10517
。
可以使用 jmap -dump:[live,]format=b,file=<file> <pid>
对目标 JVM 进行快照转储,例如:
1 | 只转储存活对象: 使用 hprof 二进制形式, 输出 jvm 的 heap 内容到文件 |
jmap(Memory Map)和 jhat(Java Heap Analysis Tool)
jmap 用来查看堆内存使用状况,一般结合 jhat 使用。
可以输出所有内存中对象的工具(如:产生那些对象,及其数量),甚至可以将 VM 中的 heap,以二进制输出成文本。
jhat
jhat 是一个原始简陋的用来分析 jmap 的堆转储快照文件的工具,Java9 之后已经被移出 JDK 的工具包。这里了解一下即可。
我们用 Java8 的 jhat 工具对刚才 jmap 转储的快照文件进行分析:
1 | jhat dump001 |
然后访问 http://localhost:7000/
就可以看到这个简陋的分析页面。
jinfo
jinfo 用于查看 JVM 参数信息,并可以实时调整少量可以在运行时改变的参数。
使用 jinfo 时要注意两点:
- 执行
jinfo
命令的用户与目标 JVM 的启动用户应该是同一个用户,避免权限不足。 jinfo
命令版本与目标 JVM 的java
命令版本一致,应该是同一个 JDK 目录下的命令。
查看目标 JVM 的完整 JVM 参数信息如下所示:
1 | # 因为之前启动的JVM使用的是 /usr/java/jdk-11.0.7+10/bin/java ,所以这里需要使用对应相同目录下的 jinfo |
jinfo 的输出内容有三部分,分别是:
Java System Properties
:JVM 运行时的环境变量VM Flags
:生效的虚拟机参数配置VM Arguments
:启动 JVM 时传入的参数、命令、及当时的对应会话的环境变量
这里要尤其注意的是,如果系统环境上不止一个 JDK,比如这里的例子,实际有两个 JDK,一个 Java8 一个 Java11,那么运行 JVM 时使用的 JDK 版本应该看 Java System Properties
里的 java.runtime.version
,而不是 VM Arguments
里的 java_class_path (initial)
。
可以使用 <pid>
只查看 JVM 运行时的环境变量。
可以使用 jinfo -flags <pid>
只查看生效的虚拟机参数配置,比如 jinfo -flags 10517
。
可以使用 jinfo -flag <name> <pid>
查看指定参数的值,比如 jinfo -flag MaxHeapSize 10517
。
可以使用 jinfo -flag [+|-]<name> <pid>
实时开启或关闭某个可以在运行时改变的参数,比如 jinfo -flag +HeapDumpOnOutOfMemoryError 10517
。
可以使用 jinfo -flag <name>=<value>
实时修改某个可以在运行时改变的参数的值,比如 jinfo -flag MaxHeapFreeRatio=75 10517
。
通过命令
java -XX:+PrintFlagsFinal <pid> | grep manageable
查看哪些参数可以在运行时改变。
jcmd
jcmd 提供了上述命令行工具的统一使用方式,如下表所示:
命令 | jcmd 命令 | jhsdb 命令 |
---|---|---|
jps -lm | jcmd | - |
jmap -dump | jcmd pid GC.heap_dump fillpath…..hpro | jhsdb jmap –binaryheap –pid |
jmap -histo | jcmd pid GC.class_histogram | jhsdb jmap –histo –pid |
jstack | jcmd pid Thread.print | jhsdb jstack –locks –pid |
jinfo -sysprops | jcmd pid VM.system_properties | jhsdb info –sysprops –pid |
jinfo -flags | jcmd pid VM.flags | jhsdb jinfo –flags –pid |
与 jcmd 具有类似功能的还有
jhsdb
,也一起列在下面的表中。jhsdb
还提供了图形化功能,在下一节介绍。
1 | 印 jvm 进程,查看 pid |
jhsdb
jhsdb 除了命令以外,还提供了图形化功能来监视分析 JVM 状况。
JDK8 没有这个命令 jhsdb 使用如下命令开启目标 JVM 的图形化分析界面:
1 | jhsdb hsdb --pid <pid> |
同样的,jhsdb 使用时,也要注意用户、版本是否与目标 JVM 一致。
打开后首先有一个线程窗口,展现当前的线程信息。
另外 tools 菜单下有很多功能按钮,比如 Class Browser
可以查看所有类信息,Heap Parameters
可以输出当前堆内存分区使用情况就像下面这样:
1 | G1 Heap: |
还有很多其他功能,大家可以慢慢尝试。
jconsole
jconsole 是一款对 JVM 的可视化监视管理工具,通过它我们可以实时地监视 JVM 的内存、线程、类加载等信息的变化趋势。
使用下面的命令启动:
1 | jconsole |
同样的,jconsole 使用时,也要注意用户、版本是否与目标 JVM 一致。
jconsole 启动后有一个选择 JVM 进程的界面,选择一个 JVM 后即可看到界面。
如果要连接一个远程机器上的 JVM,那么需要在目标机器的 JVM 上增加以下参数:
1 | -Dcom.sun.management.jmxremote |
如果想要使用密码认证和 ssl 保证通信安全,请自行搜索。
Java9 后需要单独下载的 JDK 工具
Java9 之后,部分 JVM 工具被移出了 JDK 工具包,需要单独去安装。这里介绍两个比较好用的工具。
visualVM
visualVM 是一个类似 jconsole,但是比 jconsole 的功能更强大丰富的 JVM 监视工具,还可以用来分析 jmap 的堆转储快照文件。它也可以连接远程 JVM,方法与 jconsole 的远程 JVM 一样。
visualVM 的下载地址是:
1 | https://visualvm.github.io/download.html |
下载后启动:
1 | ./visualvm --jdkhome /usr/java/jdk-11.0.7+10 |
同样的,visualVM 使用时,也要注意用户、JDK 版本是否与目标 JVM 一致。
visualVM 监视信息比 jconsole 更丰富,而且它还可以直接导入 jmap 的堆转储快照文件,并按照你需要的维度做一些简单的排序展示。
JMC
JMC,Java Mission Control
,是另一个很强大的 JVM 监视工具,和 visualVM、jconsole 一样,它可以监视 JVM 的各种数据。除此以外,它还提供了强大的 飞行记录器
功能,记录一段时间内 JVM 的各种信息,包括内存、代码、线程、IO、事件等等的记录,然后基于这些信息做性能分析。
JMC 下载地址如下:
1 | https://www.oracle.com/java/technologies/javase/products-jmc7-downloads.html |
本地启动命令:
1 | ./jmc |
页面启动后,左侧会显示本地 JVM,如果要连接远程 JVM,可以在 文件 --> 连接
菜单中创建新连接。远程 JVM 的参数配置与 jconsole 一样。
直接点击左侧菜单的目标 JVM 即可打开实时监视页面,双击左侧菜单该 JVM 下层的 飞行记录器
即可开始一次飞行记录,结束后会自动给出分析报告。
Flight Recorder
飞行记录,简称 JFR
,以前是商业 JDK 的特性,后来在 JDK11 中开源,通常可以通过 JVM 启动参数 -XX:StartFlightRecording
开启,或者通过 jcmd
相关命令录制。这里通过 JMC 工具可以可视化录制飞行记录。
JFR 是一种用于收集关于正在运行的 Java 应用程序的诊断和分析数据的工具。它集成到 Java 虚拟机(JVM)中,几乎不会造成性能开销,因此即使在负载非常大的生产环境中也可以使用它。它收集 JVM 的各种事件信息,包括:磁盘 IO、GC、线程 sleep、线程 wait、Socket read/write 等。JFR 就如同飞机上的黑匣子,通过收集的这些事件的详细信息能够更加深入了解程序的内部运行过程,这是很多其他工具所不具备的。
除了实时 JVM 监视和飞行记录分析以外,JMC 也可以直接打开并分析 jmap 的堆转储快照文件
其他工具
MAT
MAT,全称 Memory Analyzer Tool
,它是一个傻瓜式的堆转储快照文件分析工具,既可以自己生成堆转储快照文件,也可以直接分析 jmap 命令导出的快照文件。
MAT 工具可以提供以下分析:
- Histogram:列出内存中的对象,对象的个数以及大小
- Dominator Tree:列出最大的对象以及其依赖存活的 Object
- Top Consumers : 通过图形列出最大的 object
- duplicate classes :检测由多个类装载器加载的类
- Leak Suspects :内存泄漏分析
- Top Components:列出大于总堆数的百分之 1 的报表
- Component Report:分析属于同一个包或者被同一个类加载器加载的对象状况
其中最常用的就是 Leak Suspects
内存泄漏分析。
MAT 需要单独下载安装,下载地址:
1 | https://www.eclipse.org/mat/downloads.php |
MAT 是 eclipse 系的工具,类似与 Jprofiler 之于 IDEA,但它是免费的,不像 Jprofiler 还收费。。。
下载到本地解压后直接运行 MemoryAnalyzer
即可。
使用也很简单,首页点击 Open heap dump
,然后选择对应的堆转储快照文件即可。
我们一般是在 JVM 启动参数添加 -XX:+HeapDumpOnOutOfMemoryError
让 JVM 在发生内存溢出异常时自动 dump 堆快照文件,所以分析时最重要的就是找出数量和空间消耗最大的对象信息,并通过调用堆栈信息查找可能发生内存泄露的代码所在。
而通过 MAT 的 Leak Suspects
功能,就能直接给出一个内存泄露分析报告,更多相关信息请查看官方文档:
http://wiki.eclipse.org/Memory
IBM HeapAnalyzer
MAT 在分析内存泄露时,虽然能快速定位发生内存溢出异常时占用空间最多的对象,但这些对象往往是很底层的对象,我们要通过堆栈调用去找到真正代码中产生泄露的地方。而 MAT 貌似没有直观展现调用关系树的功能,这时我们可以使用 IBM HeapAnalyzer
这个工具。
IBM HeapAnalyzer
的下载和使用参考下面的地址:
1 | https://www.ibm.com/support/pages/node/1109955?mhsrc=ibmsearch_a&mhq=heapanalyzer |
它与 MAT 一样,也可以自动做内存泄露分析,比 MAT 更好的地方是,它对堆栈调用做了可视化的转换,可以更直观地看到调用关系树。
IBM HeapAnalyzer
最大的问题是,它已经很久没有更新维护了。。。
Jprofiler
JProfiler 是由 ej-technologies 公司开发的一款性能瓶颈分析工具。它是一款优秀的商业软件,功能非常丰富,因此具备一些免费软件所不具备的功能。Jprofiler 提供的主要功能有内存视图、CPU 视图、线程视图、堆遍历器(Heap Walker)等。
它与 MAT,IBM HeapAnalyzer 一样,可以用于分析堆转储快照文件。但由于收费,这里就不介绍了。
Arthas
前面所有的 JVM 工具,都是基于 JVM 自己提供的 MBeans/JMX 技术,或者 JFR 技术去监视 JVM 状态。要么是监视 JVM 运行时数据,要么是 OOM 之后的堆转储快照文件的离线分析。
如果我们要找到一个 JVM 运行时的性能瓶颈所在,我们需要监视运行时内存、线程、CPU 等资源的变化,并找到对应时间段的对象或线程来定位具体比较消耗资源的代码。这种方式实际操作起来还是很麻烦的。
而 Arthas 就是一个在实时监视跟踪具体方法方面特别强大的一种 JVM 在线调试工具。Arthas 提供了在线的方法级别的监视跟踪功能。比如 monitor/watch/trace 等指令,通过字节码增强技术,直接在代码字节码层面做插桩,实现对运行时方法调用链、耗时、返回数据等信息的动态实时监视。
Arthas 的安装与使用可以直接参考官方文档,上手很简单:
1 | https://arthas.aliyun.com/doc/index.html |
除了 JMC 的 JFR 飞行记录,其他 JVM 工具所能监视的信息,基本上 Arthas 也都具备对应功能。而除了这些 JVM 信息查看、运行时状况监视。以及方法的实时监视跟踪之外,Arthas 还有在线编译与反编译的功能,对于某些场景下的临时验证,或确认部署版本是否正确等特殊需求而言,十分方便。
但 arthas 在使用时,会对 JVM 的字节码造成入侵,会占用部分资源,对系统整体性能有一定的影响。所以相比于其他工具,arthas 其实是一个开发人员的调试工具,而不是 JVM 运维工具。
JVM 工具总结
JVM 运维与调试工具当然并不是仅仅只有本章节所列举的这些,但一般而言,这些工具掌握部分也就满足平时的需要了。这里对它们进行一个简单的总结。
- 当你只是简单地查看 JVM 运行时的状况时,你可以直接使用 JDK 自带的那些工具命令,比如
jps
、jinfo
等等。 - 当你需要在 OOM 时查看内存泄露原因时,可以直接在 JVM 参数中配置 OOM 自动 dump 堆转储快照文件,并配合
jmap
等工具手动或定时周期性地 dump 堆快照。 - 当你想实时监视 JVM 的内存、线程、CPU 等资源消耗趋势时,你可以使用
jconsole
、visualVM
、JMC
等工具。 - 当你想全面监视 JVM 各种事件信息,包括磁盘 IO、GC、线程 sleep、线程 wait、Socket read/write 等等,且不想对 JVM 性能带去影响时,你可以通过 JMC 录制 JFR 飞行记录,并在 JMC 中查看报告。
- 当你需要在方法层面上监视跟踪其调用链路,耗时及返回值时,你可以使用 arthas 这样的在线 JVM 调试工具。
个人认为作为保底手段,无论是 JVM 运维还是开发调试,JDK 自带的那些工具比如 jps
、jinfo
、jstat
、jstack
等,我们都应该要学习如何使用。
对于偏向于 JVM 运维的可视化监视方面,推荐使用 JMC,并尝试录制 JFR 飞行记录。对于专业的 JVM 运维,以及编写各种性能分析报告来说,这个工具很有用。
而对于开发人员来说,目前最推荐的工具是 arthas
,基本上 JVM 调试需要的功能它都有。
java 命令行参数
不同的 JDK 版本,对应的 java 命令行参数并不完全一致。java 命令行的参数基本上可以分为三类:
- 标准选项
Standard options
,大部分与 JVM 设置无关,比如-cp
指定类目录或 jar 文件,比如-D
设置运行时环境变量,等等。基本上所有 JVM 都支持它们,可以直接通过java
命令或java --help
命令查看。 - 非标准选项
Non-standard options
,以-X
开头,主要是针对 JVM 的一些参数,比如-Xmx
设置最大堆大小,比如-Xms
设置初始堆大小,等等。不同 OS 不同 JVM 支持的-X
选项是不尽相同的,可以通过java -X
查看。 - 高级选项
Advanced options
,以-XX
开头,主要是用于 JVM 调优的高级参数,比如-XX:+HeapDumpOnOutOfMemoryError
开启 OOM 时自动 dump 堆存储文件。一般不建议日常使用。不同 OS 不同 JVM 支持的-XX
选项也是不尽相同的,通常是运维人员对 JVM 进行调优时才会用到。
关于 Java 命令行参数,目前没有一个比较完整比较好的参考文档,可以看看下面几个文档:
1 | # JDK7及之前的一些-XX高级选项 |