JVM性能调优之运行时参数小结
作者:布道师小羊
熟悉JVM参数对于系统调优是非常重要的。比如一个高流量的延迟的电子交易平台,它要求的响应时间都是毫秒级的。要获得适合的参数组合需要大量的分析和不断地尝试,更依赖交易系统的特性。
本帖将主要讲解JVM的运行时参数的分类及其使用方式。
1、JVM参数选项类型
JVM参数总体上来说分为三大类,分别是标准参数选项、非标准参数选项和非稳定参数选项,下面分别详细介绍三大参数类型。
1.1、标准参数选项
所有的JVM都必须实现标准参数的功能,而且向后兼容。标准参数是相对比较稳定的参数,后续版本基本不会发生变化,参数以“-”开头,例如大家常见的“-version”参数就是标准参数。获取标准参数的命令是在终端输入“java”或者“java -help”命令即可,获取结果如下表所示:
需要注意的是HotSpot虚拟机的两种模式,分别是Server和Client,分别通过-server和-client模式设置。
在32位Windows系统上,默认使用Client类型的JVM。要想使用Server模式,则机器配置至少有2个以上的CPU和2GB以上的物理内存。Client模式适用于对内存要求较小的桌面应用程序,默认使用Serial串行垃圾收集器。
64位机器上只支持Server模式的JVM,适用于需要大内存的应用程序,默认使用并行垃圾收集器。
1.2、非标准参数选项
我们知道JVM可以有不同的生产厂商,非标准参数的意思是并不保证所有JVM都对非标准参数进行实现,即只能被部分JVM识别且不保证向后兼容,功能相对来说也是比较稳定的,但是后续版本有可能会变更,参数以“-X”开头。可以用java -X来检索非标准参数,不能保证所有参数都可以被检索出来,例如其中就没有-Xcomp。下表列出了常见的非标准参数。
特别注意的是-Xint参数表示禁用JIT,所有的字节码都被解释执行,这个模式下系统启动最快,但是执行效率最低。-Xcomp表示JVM采用编译模式,代码执行很快,但是启动会比较慢。-Xmixed表示JVM采用混合模式,启动速度较快,让JIT根据程序运行的情况,对热点代码实行检测和编译。
虽然-Xms、-Xmx和-Xss三个参数归属于-X参数选项,但是这三个参数的执行效果分别等同于非稳定参数中的-XX:InitialHeapSize、-XX:MaxHeapSize和-XX:ThreadStackSize。
1.3、非稳定参数选项
非稳定参数选项以-XX开头,也属于非标准参数,相对不稳定,在JVM中是不健壮的,也可能会突然直接取消某项参数,主要用于JVM调优和调试。但是这些参数中有很多参数对于JVM调优很有用处,所以也是使用最多的参数选项。
-XX参数又分为布尔类型参数和非布尔类型参数。布尔类型的格式为-XX:+/-,-XX:+表示启用option,-XX:-表示禁用option。例如-XX:+UseParallelGC表示开启ParallelGC垃圾收集器,-XX:-UseParallelGC表示关闭ParallelGC垃圾收集器,有些参数是默认开启的,调优的时候可以考虑关闭某些参数。
非布尔类型的参数也可以理解为Key-Value型的参数,可以分为数值类型和非数值类型。数值类型格式为-XX:=,number可以带上单位(k、K表示千字节,m、M表示兆,或者使用更大的内存单位g、G),例如-XX:NewSize=1024m表示设置新生代初始大小为1024MB。非数值类型格式为-XX:=,例如-XX:HeapDumpPath=/usr/local/heapdump.hprof用来指定heap转存文件的存储路径。
通过“java -XX:+PrintFlagsFinal”命令可以查看所有的-XX参数,如下图所示,篇幅原因截取部分截图。
上图最后一列参数的取值有多种,如下所示:
- (1)product表示该类型参数是官方支持的,属于JVM内部选项。
- (2)rw表示可动态写入。
- (3)C1表示Client JIT编译器。
- (4)C2表示Server JIT编译器。
- (5)pd表示平台独立。
- (6)lp64表示仅支持64位JVM。
- (7)manageable表示可以运行时修改。
- (8)diagnostic表示用于JVM调试。
- (9)experimental表示非官方支持的参数。
默认不包含diagnostic和experimental两种类型,想要包含该类型的参数可以配合参数-XX:+UnlockDiagnosticVMOptions和-XX:+UnlockExperimentalVMOptions使用,例如java-XX:+PrintFlagsFinal -XX:+UnlockDiagnosticVMOptions命令结果如下(部分结果),包含了diagnostic类型的参数。同理可以添加-XX:+UnlockExperimentalVMOptions参数用于包含experimental类型的参数,不再演示。
2、添加JVM参数的方式
在工作中经常需要配置JVM参数,一般有以下几种方式:
2.1、IDEA界面配置
鼠标右键选中目标工程,选择“Run”→“Edit Configurations”选项,选中要添加JVM参数的Application,然后在Configuration里面的VM options中输入想要添加的JVM参数即可,如下图所示,例如填入-Xmx256m,这样就可以设置运行时最大内存为256MB。
2.2、通过java命令配置
通过java命令运行class或者jar包的时候也可以添加JVM参数,一般多用于工程测试,如下所示:
//运行jar包时添加JVM参数 java -Xms128m -Xmx256m -jar demo.jar //运行类的字节码文件时添加JVM参数 java -Xms128m -Xmx256m 类名
2.3、通过web服务器配置
Linux系统下可以在tomcat/bin/catalina.sh中添加如下JVM配置。
JAVA_OPTS="-Xms512M -Xmx1024M"
Windows系统下可以在catalina.bat中添加如下配置。
set"JAVA_OPTS=-Xms512M -Xmx1024M"
2.4、通过jinfo命令配置
3、常用JVM参数选项
JVM参数选项那么多,在工作中有很多参数是很少用到的,这里汇总了几大常用的参数分类,如下所示:
(1)输出设置的-XX参数以及参数值的参数选项如下表所示:
(2)堆、栈、方法区等内存大小设置的参数选项如下表所示:
(3)OutOfMemory相关的参数选项如下表所示:
-XX:OnOutOfMemoryError表示当发生内存溢出的时候,还可以让JVM调用任一个shell脚本。大多数时候,内存溢出并不会导致整个应用都挂掉,但是最好还是把应用重启一下,因为一旦发生了内存溢出,可能会让应用处于一种不稳定的状态,一个不稳定的应用可能会提供错误的响应。例如使用以下命令:
-XX:OnOutOfMemoryError=/opt/Server/restart.sh
当给JVM传递上述参数的时候,如果发生了内存溢出,JVM会调用/opt/Server/restart.sh这个脚本,在这个脚本中可以去用优雅的办法来重启应用。restart.sh脚本如下所示。
(4)垃圾收集器相关的参数选项因垃圾收集器的不同而不同,关于垃圾收集器的分类以及配合使用。使用-XX:+PrintCommandLineFlags查看命令行相关参数,从中可以查看到当前系统使用的垃圾收集器,也可以使用命令行指令jinfo查看。
Serial收集器作为HotSpot中Client模式下的默认新生代垃圾收集器。Serial Old收集器是运行在Client模式下默认的老年代的垃圾收集器。-XX:+UseSerialGC参数可以指定新生代和老年代都使用串行收集器,表示新生代用Serial GC,且老年代用Serial Old收集器。可以获得最高的单线程收集效率。现在已经很少使用Serial收集器了。
ParNew收集器可以使用-XX:+UseParNewGC参数指定。它表示新生代使用并行收集器,不影响老年代。Parallel收集器的相关JVM参数选项如下表:
CMS收集器的相关JVM参数选项如下表所示:
需要注意的是JDK 9新特性中CMS被标记为Deprecate了,如果对JDK 9及以上版本的HotSpot虚拟机使用参数-XX:+UseConcMarkSweepGC来开启CMS收集器的话,用户会收到一个警告信息,提示CMS未来将会被废弃。JDK 14新特性中删除了CMS垃圾收集器,如果在JDK 14中使用-XX:+UseConcMarkSweepGC的话,JVM不会报错,只是给出一个warning信息,但是不会exit。JVM会自动回退以默认GC方式启动JVM。
G1收集器的相关JVM参数选项如下表所示:
G1收集器主要涉及Mixed GC,Mixed GC会回收新生代和部分老年代,G1关于Mixed GC调优常用参数选项如下表所示:
(5)GC日志相关的参数选项如下表所示:
(6)其他常用的参数选项如下表所示:
4、通过Java代码获取JVM参数
Java提供了java.lang.management包用于监视和管理JVM和Java运行时中的其他组件,它允许本地和远程监控和管理运行的JVM,会经常使用到其中的ManagementFactory类。另外还有Runtime类也可以获取一些内存、CPU核数等相关的数据。通过这些API可以监控我们的应用服务器的堆内存使用情况,也可以设置一些阈值进行报警等处理,代码清单如下演示了Java代码获取应用的内存使用情况:
运行结果如下,可以看到堆内存的各项信息:
5、小结
讲解了JVM运行时参数,JVM参数对于系统调优是非常重要的,参数分为三类,分别是标准参数选项、非标准参数选项和非稳定参数选项。标准参数是所有的JVM实现都必须要实现的参数,不同的JVM拥有相同的参数功能。非标准参数无法保证所有的JVM都会有对应的实现,该类型参数一般以“-X”开头。非稳定参数在JVM中是不健壮的,属于试验性质的参数,有可能在不同的JVM版本中会被取消,该类型参数一般以“-XX”开头,对于JVM调优有很大的用处。
到此这篇关于JVM性能调优之运行时参数小结的文章就介绍到这了,更多相关JVM 运行时参数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!