jps:Java Virtual Machine Process Status Tool
查看Java进程 ,相当于Linux下的ps命令,只不过它只列出Java进程。
jps :列出Java程序进程ID和Main函数名称
jps -q :只输出进程ID
jps -m :输出传递给Java进程(主函数)的参数
jps -l :输出主函数的完整路径
jps -v :显示传递给Java虚拟的参数
jstat:JVM Statistics Monitoring Tool
jstat可以查看Java程序运行时相关信息,可以通过它查看堆信息的相关情况
jstat - [-t] [-h] [ []]
options:由以下值构成
-class:显示ClassLoader的相关信息
-compiler:显示JIT编译的相关信息
-gc:显示与GC相关信息
-gccapacity:显示各个代的容量和使用情况
-gccause:显示垃圾收集相关信息(同-gcutil),同时显示最后一次或当前正在发生的垃圾收集的诱发原因
-gcnew:显示新生代信息
-gcnewcapacity:显示新生代大小和使用情况
-gcold:显示老年代信息
-gcoldcapacity:显示老年代大小
-gcpermcapacity:显示永久代大小
-gcutil:显示垃圾收集信息
示例一:
下面输出的是GC信息,34784 是 进程ID ,采样时间间隔为250ms,采样数为4。
jstat -gc 30108 250 4
S0C:年轻代中第一个survivor(幸存区)的容量 (单位kb)
S1C:年轻代中第二个survivor(幸存区)的容量 (单位kb)
S0U :年轻代中第一个survivor(幸存区)目前已使用空间 (单位kb)
S1U :年轻代中第二个survivor(幸存区)目前已使用空间 (单位kb)
EC :年轻代中Eden(伊甸园)的容量 (单位kb)
EU :年轻代中Eden(伊甸园)目前已使用空间 (单位kb)
OC :Old代的容量 (单位kb)
OU :Old代目前已使用空间 (单位kb)
MC:metaspace(元空间)的容量 (单位kb)
MU:metaspace(元空间)目前已使用空间 (单位kb)
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC :从应用程序启动到采样时年轻代中gc次数
YGCT :从应用程序启动到采样时年轻代中gc所用时间(s)
FGC :从应用程序启动到采样时old代(全gc)gc次数
FGCT :从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT:从应用程序启动到采样时gc用的总时间(s)
示例二:
jstat -gcutil 30108 1s 5
# 1s每隔1秒采样一次
# 共采样五次
S0 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
S1 年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
E 年轻代中Eden(伊甸园)已使用的占当前容量百分比
O old代已使用的占当前容量百分比
M metaspace已使用的占当前容量百分比
CCS 压缩使用比例
YGC 从应用程序启动到采样时年轻代中gc次数
YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
FGC 从应用程序启动到采样时old代(全gc)gc次数
FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT 从应用程序启动到采样时gc用的总时间(s)
jinfo:Java Configuration Info
jinfo可以用来查看正在运行的java程序的扩展参数,甚至支持运行时,修改部分参数
jinfo [option]
-flags 打印虚拟机 VM 参数
-flag <name> 打印指定虚拟机 VM 参数
-flag [+|-]<name> 打开或关闭虚拟机参数
-flag <name>=<value> 设置指定虚拟机参数的值
示例:
jinfo -flags 30108
jmap:Memory Map
jmap用来查看堆内存使用状况,一般结合jhat使用。
jmap语法格式如下:
Usage:
jmap [option]
(to connect to running process)
jmap [option]
(to connect to a core file)
jmap [option] [server_id@]
(to connect to remote debug server)
where
参数:
option: 选项参数。
pid: 需要打印配置信息的进程ID。
executable: 产生核心dump的Java可执行文件。
core: 需要打印配置信息的核心文件。
server-id: 可选的唯一id,如果相同的远程主机上运行了多台调试服务器,用此选项参数标识服务器。
remote server IP or hostname 远程调试服务器的IP地址或主机名。
option
no option: 查看进程的内存映像信息,类似 Solaris pmap 命令。
heap: 显示Java堆详细信息
histo[:live]: 显示堆中对象的统计信息
clstats:打印类加载器信息
finalizerinfo: 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
dump::生成堆转储快照
F: 当-dump没有响应时,使用-dump或者-histo参数. 在这个模式下,live子参数无效.
help:打印帮助信息
J:指定传递给运行jmap的JVM的参数
示例一:no option
命令:jmap pid
描述:查看进程的内存映像信息,类似 Solaris pmap 命令。
使用不带选项参数的jmap打印共享对象映射,将会打印目标虚拟机中加载的每个共享对象的起始地址、映射大小以及共享对象文件的路径全称。这与Solaris的pmap工具比较相似。
jmap 30108
示例二:heap
命令:jmap -heap pid
描述:显示Java堆详细信息
打印一个堆的摘要信息,包括使用的GC算法、堆配置信息和各内存区域内存使用信息
示例三:histo[:live]
命令:jmap -histo:live pid
描述:显示堆中对象的统计信息
其中包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果ja指定了live子选项,则只计算活动的对象。
示例四:clstats
命令:jmap -clstats pid
描述:打印类加载器信息
-clstats是-permstat的替代方案,在JDK8之前,-permstat用来打印类加载器的数据
打印Java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。
示例五:finalizerinfo
命令:jmap -finalizerinfo pid
描述:打印等待终结的对象信息
Number of objects pending for finalization: 0 说明当前F-QUEUE队列中并没有等待Fializer线程执行final
示例六:dump:
命令:jmap -dump:format=b,file=heapdump.hprof pid
描述:生成堆转储快照dump文件。
以hprof二进制格式转储Java堆到指定filename的文件中。live子选项是可选的。如果指定了live子选项,堆中只有活动的对象会被转储。想要浏览heap dump,你可以使用jhat(Java堆分析工具)读取生成的文件。
这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用, 线上系统慎用。
jhat:Java Heap Analysis Tool,jhat 命令解析Java堆转储文件,并启动一个 web server. 然后用浏览器来查看/浏览 dump 出来的 heap. jhat 命令支持预先设计的查询, 比如显示某个类的所有实例. 还支持 对象查询语言(OQL, Object Query Language)。 OQL有点类似SQL,专门用来查询堆转储。 OQL相关的帮助信息可以在 jhat 命令所提供的服务器页面最底部. 如果使用默认端口, 则OQL帮助信息页面为: http://localhost:7000/oqlhelp/
Java生成堆转储的方式有多种:
jmap -dump
选项可以在JVM运行时获取 heap dump.jconsole
选项通过 HotSpotDiagnosticMXBean 从运行时获得堆转储。-XX:+HeapDumpOnOutOfMemoryError
选项, 则抛出 OutOfMemoryError 时, 会自动执行堆转储。hprof
命令。jhat [ options ] heap-dump-file
参数:
#
的方式指定解析哪一个 dump, 如: myfile.hprof#3
Options
-stack false|true
关闭对象分配调用栈跟踪(tracking object allocation call stack)。 如果分配位置信息在堆转储中不可用. 则必须将此标志设置为 false. 默认值为 true
.
-refs false|true
关闭对象引用跟踪(tracking of references to objects)。 默认值为 true
. 默认情况下, 返回的指针是指向其他特定对象的对象,如反向链接或输入引用(referrers or incoming references), 会统计/计算堆中的所有对象。
-port port-number
设置 jhat HTTP server 的端口号. 默认值 7000
.
-exclude exclude-file
指定对象查询时需要排除的数据成员列表文件(a file that lists data members that should be excluded from the reachable objects query)。 例如, 如果文件列列出了 java.lang.String.value
, 那么当从某个特定对象 Object o 计算可达的对象列表时, 引用路径涉及 java.lang.String.value
的都会被排除。
-baseline exclude-file
指定一个基准堆转储(baseline heap dump)。 在两个 heap dumps 中有相同 object ID 的对象会被标记为不是新的(marked as not being new). 其他对象被标记为新的(new). 在比较两个不同的堆转储时很有用.
-debug int
设置 debug 级别. 0
表示不输出调试信息。 值越大则表示输出更详细的 debug 信息.
-version
启动后只显示版本信息就退出
-h
显示帮助信息并退出. 同 -help
-help
显示帮助信息并退出. 同 -h
-J< flag >
因为 jhat 命令实际上会启动一个JVM来执行, 通过 -J 可以在启动JVM时传入一些启动参数. 例如, -J-Xmx512m
则指定运行 jhat 的Java虚拟机使用的最大堆内存为 512 MB. 如果需要使用多个JVM启动参数,则传入多个 -Jxxxxxx.
示例一:
利用jhat分析刚刚jmap输出的堆文件:
这样就启动起来了一个简易的HTTP服务,端口号是7000,尝试一下用浏览器访问一下它,本地的可以通过http://localhost:7000就可以得到这样的页面:
jhat 启动后显示的 html 页面中包含有:
jstack:Java Stack Trace,jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。
在thread dump中,要留意下面几种状态
使用方式
jstack [ option ] pid 查看当前时间点,指定进程的dump堆栈信息。
jstack [ option ] pid > 文件 将当前时间点的指定进程的dump堆栈信息,写入到指定文件中。 注:若该文件不存在,则会自动生成;若该文件存在,则会覆盖源文件。
jstack [ option ] executable core 查看当前时间点,core文件的dump堆栈信息。
jstack [ option ] [server_id@] 查看当前时间点,远程机器的dump堆栈信息。
可选参数说明
-F 当进程挂起了,此时'jstack [-l] pid'是没有相应的,这时候可使用此参数来强制打印堆栈信息,强制jstack),一般情况不需要使用。
-m 打印java和native c/c++框架的所有栈信息。可以打印JVM的堆栈,以及Native的栈帧,一般应用排查不需要使用。
-l 长列表. 打印关于锁的附加信息。例如属于java.util.concurrent的ownable synchronizers列表,会使得JVM停顿得长久得多(可能会差很多倍,比如普通的jstack可能几毫秒和一次GC没区别,加了-l 就是近一秒的时间),-l 建议不要用。一般情况不需要使用。
-h or -hel 打印帮助信息
示例一:
将指定进程的当前堆栈情况记录到某个文件中:
示例二:
统计线程数
jstack -l 30108 | grep 'java.lang.Thread.State' | wc -l
开发大型 Java 应用程序的过程中难免遇到内存泄露、性能瓶颈等问题,比如文件、网络、数据库的连接未释放,未优化的算法等。随着应用程序的持续运行,可能会造成整个系统运行效率下降,严重的则会造成系统崩溃。为了找出程序中隐藏的这些问题,在项目开发后期往往会使用性能分析工具来对应用程序的性能进行分析和优化。
VisualVM 是一款免费的性能分析工具。它通过 jvmstat、JMX、SA(Serviceability Agent)以及 Attach API 等多种方式从程序运行时获得实时数据,从而进行动态的性能分析。同时,它能自动选择更快更轻量级的技术尽量减少性能分析对应用程序造成的影响,提高性能分析的精度。
性能分析的主要方式
监视是一种用来查看应用程序运行时行为的一般方法。通常会有多个视图(View)分别实时地显示 CPU 使用情况、内存使用情况、线程状态以及其他一些有用的信息,以便用户能很快地发现问题的关键所在。
性能分析工具从内存中获得当前状态数据并存储到文件用于静态的性能分析。Java 程序是通过在启动 Java 程序时添加适当的条件参数来触发转储操作的。它包括以下三种:
系统转储:JVM 生成的本地系统的转储,又称作核心转储。一般的,系统转储数据量大,需要平台相关的工具去分析,如 Windows 上的 windbg 和 Linux 上的 gdb。
Java 转储:JVM 内部生成的格式化后的数据,包括线程信息,类的加载信息以及堆的统计数据。通常也用于检测死锁。
堆转储:JVM 将所有对象的堆内容存储到文件。
应用程序启动后,性能分析工具开始收集各种运行时数据,其中一些数据直接显示在监视视图中,而另外大部分数据被保存在内部,直到用户要求获取快照,基于这些保存的数据的统计信息才被显示出来。快照包含了应用程序在一段时间内的执行信息,通常有 CPU 快照和内存快照两种类型。
CPU 快照:主要包含了应用程序中函数的调用关系及运行时间,这些信息通常可以在 CPU 快照视图中进行查看。
内存快照:主要包含了内存的分配和使用情况、载入的所有类、存在的对象信息及对象间的引用关系等。这些信息通常可以在内存快照视图中进行查看。
性能分析是通过收集程序运行时的执行数据来帮助开发人员定位程序需要被优化的部分,从而提高程序的运行速度或是内存使用效率,主要有以下三个方面:
CPU 性能分析:CPU 性能分析的主要目的是统计函数的调用情况及执行时间,或者更简单的情况就是统计应用程序的 CPU 使用情况。通常有 CPU 监视和 CPU 快照两种方式来显示 CPU 性能分析结果。
内存性能分析:内存性能分析的主要目的是通过统计内存使用情况检测可能存在的内存泄露问题及确定优化内存使用的方向。通常有内存监视和内存快照两种方式来显示内存性能分析结果。
线程性能分析:线程性能分析主要用于在多线程应用程序中确定内存的问题所在。一般包括线程的状态变化情况,死锁情况和某个线程在线程生命期内状态的分布情况等
远程可视化监控JVM
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=172.26.233.198
-Dcom.sun.management.jmxremote.rmi.port=9999
#JAVA_OPT="${JAVA_OPT} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=172.26.233.198 -Dcom.sun.management.jmxremote.rmi.port=9999"
https://gceasy.io/
业界首先采用机器学习算法解决GC日志分析问题,GCeasy内置机器智能可以自动检测JVM和Android GC日志中的问题,并推荐解决方案。
GC日志分析是免费的,Machine Learning收费
MAT是一个强大的内存分析工具,可以快捷、有效地帮助我们找到内存泄露,减少内存消耗分析工具。MAT是Memory Analyzer tool的缩写,是一种快速,功能丰富的Java堆分析工具,能帮助你查找内存泄漏和减少内存消耗。很多情况下,我们需要处理测试提供的hprof文件,分析内存相关问题,那么MAT也绝对是不二之选。
使用MAT,可以轻松实现以下功能:
找到最大的对象,因为MAT提供显示合理的累积大小(retained size)
探索对象图,包括inbound和outbound引用,即引用此对象的和此对象引出的
查找无法回收的对象,可以计算从垃圾收集器根到相关对象的路径
找到内存浪费,比如冗余的String对象,空集合对象。
MAT安装有两种方式,一种是以eclipse插件方式安装,一种是独立安装。在MAT的官方文档中有相应的安装文件下载,下载地址为:https://www.eclipse.org/mat/downloads.php
将对象树转换成Dominator Tree能帮助我们快速的发现占用内存最大的块,也能帮我们分析对象之间的依赖关系。Dominator Tree有以下几个定义:
对象树和Dominator tree的对应关系如下:
如上图,因为A和B都引用到C,所以A释放时,C内存不会被释放。所以这块内存不会被计算到A或者B的Retained Heap中,因此,对象树在转换成Dominator tree时,会A、B、C三个是平级的。
GCViewer是一款开源的GC日志分析工具。项目的 GitHub 主页对各个指标提供了完整的描述信息 需要安装jdk才能使用。借助GCViewer日志分析工具,可以非常直观地分析出待调优点。可从以下几方面来分析:
Memory:分析Totalheap、Tenuredheap、Youngheap内存占用率及其他指标,理论上内存占用率越小越好;
Pause:分析Gc pause、Fullgc pause、Total pause三个大项中各指标,理论上GC次数越少越好,GC时长越小越好;
配置开启GC日志
用法
下载https://github.com/chewiebug/GCViewer/releases
# 分析gc日志,打开图形化界面
java -jar gcviewer-1.36.jar gc.log
# 分析gc日志,不打卡图形化界面,将结果直接生成
java -jar gcviewer-1.36.jar gc.log summary.csv chart.png
图表 + 摘要
统计图表
顶部的黑色线都代表Full GC,也可以理解为Major GC,是根据日志中的CMS GC统计的;底部灰色线代表的是Minor GC。
摘要summary
下一步就该使用 JVM 命令进行问题定位了,但很多研发可能由于自身工作经验不足、对 Java 内存模型理解不深、尚未掌握 JVM 排查命令等原因对 JVM 相关排查畏手畏脚,不够自信,进而影响排查进度。针对这种情况,本文推荐一款开源的 Java 诊断工具,对 JVM 不熟的研发可以尝试学习使用下。相对 JVM 命令来说简单多了。
Arthas 是 Alibaba 开源的 Java 诊断工具,深受开发者喜爱。
当你遇到以下类似问题而束手无策时,Arthas 可以帮助你解决:
Arthas 支持 JDK 6+,支持 Linux、Mac、Winodws,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。
# 下载arthas-boot.jar
curl -O https://alibaba.github.io/arthas/arthas-boot.jar
# 打印帮助信息:
java -jar arthas-boot.jar -h
# 启动
java -jar arthas-boot.jar
# 选择应用java进程:
[INFO] arthas-boot version: 3.5.3
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 31480 org.apache.catalina.startup.Bootstrap
[2]: 30108 /root/hero_web-1.0-SNAPSHOT-default.jar
# Demo进程是第2个,则输入2,再输入回车/enter。Arthas会attach到目标进程上,并输出日志:
[INFO] Start download arthas from remote server: https://arthas.aliyun.com/download/3.5.4?mirror=aliyun
[INFO] Download arthas success.
[INFO] arthas home: /root/.arthas/lib/3.5.4/arthas
[INFO] Try to attach process 30108
[INFO] Attach process 30108 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://arthas.aliyun.com/doc
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html
version 3.5.4
main_class
pid 30108
time 2021-10-12 11:24:34
[arthas@30108]$
-b
选项可以一键检测死锁支持管道:
Arthas支持使用管道对上述命令的结果进行进一步的处理,如sm java.lang.String * | grep 'index'
后台异步任务:
当线上出现偶发的问题,比如需要watch某个条件,而这个条件一天可能才会出现一次时,异步后台任务就派上用场了,详情请参考这里
用户数据回报:
在3.1.4
版本后,增加了用户数据回报功能,方便统一做安全或者历史数据统计。
在启动时,指定stat-url
,就会回报执行的每一行命令,比如: ./as.sh --stat-url 'http://192.168.10.11:8080/api/stat'
在tunnel server里有一个示例的回报代码,用户可以自己在服务器上实现
这里只列出常用命令,完整列表参考命令列表:
https://alibaba.github.io/arthas/commands.html
其他特性
Arthas 使用上相对 JVM 命令简单很多,即便是工作年限不多的小伙伴学起来也很快。熟练使用 Arthas 应该能诊断出大部分线上应用问题,但生产环境通常不允许擅自拷贝 jar 包,而且 Arthas 会拖慢应用本身,如果条件不允许,又该如何诊断呢?这边简单介绍下 jdk 自带的命令行工具。
输入dashboard,按回车/enter
,会展示当前进程的信息,按ctrl+c
可以中断执行。
通过thread命令来获取到应用进程的线程信息
thread -1
会打印线程统计信息。
运行期通过jad来反编译项目代码
通过watch命令来查看com.hero.web.user.controller#UserController
函数的返回值:
watch com.hero.web.user.controller.UserController findByUsername returnObj
如果只是退出当前的连接,可以用quit
或者exit
命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。
如果想完全退出arthas,可以执行stop
命令。
在JVM调整过程中,主要是对JVM参数做的调整,以下我们队JVM主要参数做逐一介绍。JVM参数有很多,其实我们直接使用默认的JVM参数,不去修改都可以满足大多数情况。但是如果你想在有限的硬件资源下,部署的系统达到最大的运行效率,那么进行相关的JVM参数设置是必不可少的。下面我们就来对这些JVM参数进行详细的介绍。
JVM参数主要分为以下三种:标准参数、非标准参数、不稳定参数。
标准参数,顾名思义,标准参数中包括功能以及输出的结果都是很稳定的,基本上不会随着JVM版本的变化而变化。标准参数以-开头,如:java -version、java -jar等,通过java -help可以查询所有的标准参数,
我们可以通过 -help 命令来检索出所有标准参数。
-help 也是一个标准参数,再比如使用比较多的 -version也是。
非标准参数以-X开头,是标准参数的扩展。对应前面讲的标准化参数,这是非标准化参数。表示在将来的JVM版本中可能会发生改变,但是这类以-X开始的参数变化的比较小。
我们可以通过 Java -X 命令来检索所有-X 参数。
我们可以通过设置非标准参数来配置堆的内存分配,常用的非标准参数有:
这是我们日常开发中接触到最多的参数类型。这也是非标准化参数,相对来说不稳定,随着JVM版本的变化可能会发生变化,主要用于JVM调优和debug。
不稳定参数以-XX 开头,此类参数的设置很容易引起JVM 性能上的差异,使JVM存在极大的不稳定性。如果此类参数设置合理将大大提高JVM的性能及稳定性。
不稳定参数分为三类:
性能参数:用于JVM的性能调优和内存分配控制,如内存大小的设置;
行为参数:用于改变JVM的基础行为,如GC的方式和算法的选择;
调试参数:用于监控、打印、输出jvm的信息;
不稳定参数语法规则:
布尔类型参数值:
数字类型参数值:
字符串类型参数值:
-Xloggc:file与-verbose:gc功能类似,只是将每次GC事件的相关情况记录到一个文件中,文件的位置最好在本地,以避免网络的潜在问题。
这是我们日常开发中接触到最多的参数类型。这也是非标准化参数,相对来说不稳定,随着JVM版本的变化可能会发生变化,主要用于JVM调优和debug。
不稳定参数以-XX 开头,此类参数的设置很容易引起JVM 性能上的差异,使JVM存在极大的不稳定性。如果此类参数设置合理将大大提高JVM的性能及稳定性。
不稳定参数分为三类:
性能参数:用于JVM的性能调优和内存分配控制,如内存大小的设置;
行为参数:用于改变JVM的基础行为,如GC的方式和算法的选择;
调试参数:用于监控、打印、输出jvm的信息;
不稳定参数语法规则: