JVM参数


一、参数分类

java启动参数共分为三类;

  • 标准参数(-),所有的 JVM 实现都必须实现这些参数的功能,而且向后兼容;如 -version、-help
  • 非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容;如 -Xms、-Xmx
  • 非Stable参数(-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用;如-XX:+PrintGC

1、常用参数

(1)堆(Heap):

参数 含义 默认值 示例 使用说明
-Xms 初始堆大小(最小) 物理内存的1/64(<1GB) -Xms512M
-Xmx 最大堆大小 物理内存的1/4(<1GB) -Xmx512M 尽量设置和-Xms一样。防止因为内存不断增加后突然收缩带来的性能影响
-Xmn 新生代大小 -Xmn128M 增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
-XX:NewSize 设置新生代初始大小 -XX:NewSize128M
-XX:MaxNewSize 设置新生代最大空间大小。 -XX:MaxNewSize128M

堆空间大小 = 老年代空间大小 + 年轻代大空间大小

没有直接设置老年代的参数,但是可以设置堆空间大小和新生代空间大小两个参数来间接控制。

-Xmn 和 -XX:Newsize 区别

前者是设置堆中新生代大小。后者是设置新生代初始大小-Xmn 是将NewSize与MaxNewSize设为一致。

(2)方法区

参数 含义
-XX:PermSize 设置永久代最小空间大小。
-XX:MaxPermSize 设置永久代最大空间大小。

(3)栈/本地方法栈

参数 含义 示例 使用说明
-Xss 设置每个线程的堆栈大小。 -Xss128K 一般来说,webx框架下应用需要256K,64位Linux默认1024K

2、标准参数

各个版本之间差别不大的参数:

  • -version
  • -help

3、X参数(非标准参数)

  • -Xint:编译执行
  • -Xcomp:第一次使用就编译成本地代码
  • -Xmixed:混合模式

4、XX参数(非Stable参数)

用-XX作为前缀的参数列表在jvm中可能是不健壮的,SUN也不推荐使用,后续可能会在没有通知的情况下就直接取消了;但是由于这些参数中的确有很多是对我们很有用的,比如我们经常会见到的-XX:PermSize、-XX:MaxPermSize等等;

XX参数数值类型

  • 布尔类型。如-XX:+PrintGCDetails,其中 + 和 - 分别表示开启/关闭某个属性,PrintGCDetails表示打印GC详情
  • KV设值类型。如-XX:NewSize=256M,设置年轻代空间大小为256M

Java HotSpot VM中 -XX: 的可配置参数分类:

  • 行为参数(Behavioral Options):用于改变jvm的一些基础行为;
  • 性能调优(Performance Tuning):用于jvm的性能调优;
  • 调试参数(Debugging Options):一般用于打开跟踪、打印、输出等jvm参数,用于显示jvm更加详细的信息;

(1)行为参数

参数及其默认值 描述
-XX:-DisableExplicitGC 禁止调用System.gc();但jvm的gc仍然有效
-XX:+MaxFDLimit 最大化文件描述符的数量限制
-XX:+ScavengeBeforeFullGC 新生代GC优先于Full GC执行
-XX:+UseGCOverheadLimit 在抛出OOM之前限制jvm耗费在GC上的时间比例
-XX:-UseConcMarkSweepGC 对老生代采用并发标记交换算法进行GC
-XX:-UseParallelGC 启用并行GC
-XX:-UseParallelOldGC 对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用
-XX:-UseSerialGC 启用串行GC
-XX:+UseThreadPriorities 启用本地线程优先级

上面表格中黑体的三个参数代表着jvm中GC执行的三种方式,即串行、并行、并发

串行(SerialGC)是jvm的默认GC方式,一般适用于小型应用和单处理器,算法比较简单,GC效率也较高,但可能会给应用带来停顿;

并行(ParallelGC)是指GC运行时,对应用程序运行没有影响,GC和app两者的线程在并发执行,这样可以最大限度不影响app的运行;

并发(ConcMarkSweepGC)是指多个线程并发执行GC,一般适用于多处理器系统中,可以提高GC的效率,但算法复杂,系统消耗较大;

(2)性能调优参数

参数及其默认值 描述
-XX:LargePageSizeInBytes=4m 设置用于Java堆的大页面尺寸
-XX:MaxHeapFreeRatio=70 GC后java堆中空闲量占的最大比例
-XX:MaxNewSize=size 新生成对象能占用内存的最大值
-XX:MaxPermSize=64m JVM最大容许分配的非堆内存
-XX:MinHeapFreeRatio=40 GC后java堆中空闲量占的最小比例
-XX:NewRatio=2 新生代内存容量与老生代内存容量的比例
-XX:NewSize=2.125m 新生代对象生成时占用内存的默认值
-XX:ReservedCodeCacheSize=32m 保留代码占用的内存容量
-XX:ThreadStackSize=512 设置线程栈大小,若为0则使用系统默认值(简写-Xss)
-XX:+UseLargePages 使用大页面内存

在日常性能调优中基本上都会用到以上黑体的这几个属性;

堆相关参数:-Xms-Xmx,这两个参数属于 XX 参数,因为这种写法是缩写

参数缩写 原始参数 描述
-Xms -XX:InitialHeapSize 设置初始堆容量
-Xmx -XX:MaxHeapSize 设置最大堆容量

这两个参数用法如下:-Xms128M

栈相关参数:

参数缩写 原始参数 描述
-Xss -XX:ThreadStackSize 设置线程栈大小,若为0则使用系统默认值(默认512~1024K)(64位Linux为1024K)

(3)调试参数

参数及其默认值 描述
-XX:-CITime 打印消耗在JIT编译的时间
-XX:ErrorFile=./hs_err_pid<pid>.log 保存错误日志或者数据到文件中
-XX:-ExtendedDTraceProbes 开启solaris特有的dtrace探针
-XX:HeapDumpPath=./java_pid<pid>.hprof 指定导出堆信息时的路径或文件名
-XX:-HeapDumpOnOutOfMemoryError 当首次遭遇OOM时导出此时堆中相关信息
-XX:OnError="<cmd args>;<cmd args>" 出现致命ERROR之后运行自定义命令
-XX:OnOutOfMemoryError="<cmd args>;<cmd args>" 当首次遭遇OOM时执行自定义命令
-XX:-PrintClassHistogram 遇到Ctrl-Break后打印类实例的柱状信息, 与jmap -histo功能相同
-XX:-PrintConcurrentLocks 遇到Ctrl-Break后打印并发锁的相关信息, 与jstack -l功能相同
-XX:-PrintCommandLineFlags 打印在命令行中出现过的标记
-XX:-PrintCompilation 当一个方法被编译时打印相关信息
-XX:-PrintGC 每次GC时打印相关信息
-XX:-PrintGC Details 每次GC时打印详细信息
-XX:-PrintGCTimeStamps 打印每次GC的时间戳
-XX:-TraceClassLoading 跟踪类的加载信息
-XX:-TraceClassLoadingPreorder 跟踪被引用到的所有类的加载信息
-XX:-TraceClassResolution 跟踪常量池
-XX:-TraceClassUnloading 跟踪类的卸载信息
-XX:-TraceLoaderConstraints 跟踪类加载器约束的相关信息

当系统出现问题的时候,又不能使用外部跟踪工具(比如JProfiler……)的情况下,以上的这些参数就会发挥重大作用了,比如dump堆信息、打印并发锁……

二、查看 jvm 参数

1、查看运行中项目的参数

可以通过 jinfo 命令查看正在运行的 java 项目的参数

# 查看所有非默认参数
jinfo -flags java进程号

# 查看指定参数的配置
jinfo -flag 参数 进程号

输出如下

[root@VM-20-13-centos data]# jps
12038 jar
10668 Jps

[root@VM-20-13-centos data]# jinfo -flags 12038
Attaching to process ID 12038, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.311-b11
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=62914560 -XX:MaxHeapSize=994050048 -XX:MaxNewSize=331350016 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=20971520 -XX:OldSize=41943040 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
Command line:  

[root@VM-20-13-centos ~]# jinfo -flag InitialHeapSize 12038
-XX:InitialHeapSize=62914560

jinfo -flags 12038 的输出中,

  • Non-default VM flags 表示参数值取决于系统(非人为设置),如默认堆大小是取决于系统内存的
  • Command line 表示在系统启动时人为设置的参数

2、查看系统默认的 jvm 参数

当java 项目在系统中运行时,很多参数会取决于系统的环境或硬件,可通过下面命令来查看所有的参数的默认值,此命令无需启动项目

java -XX:+PrintFlagsInitial

输出如下

[root@VM-20-13-centos ~]# java -XX:+PrintFlagsInitial
[Global flags]
intx ActiveProcessorCount                      = -1     {product}
uintx AdaptiveSizeDecrementScaleFactor          = 4     {product}
uintx AdaptiveSizeMajorGCDecayTimeScale         = 10    {product}

3、查看修改后的 jvm 参数

-XX:+PrintFlagsFinal

此处用 -version 来代替项目的运行

[root@VM-20-13-centos ~]# java -XX:+PrintFlagsFinal -version
[Global flags]
intx ActiveProcessorCount                      = -1          {product}
uintx InitialHeapSize                          := 62914560   {product}

在输出的参数中 = 表示默认值,没有被修改过;而 := 表示该参数值被修改过了

启动项目并修改参数如下

java -XX:+PrintFlagsFinal -XX:MetaspaceSize=512m

4、查看程序使用的默认JVM参数

-XX:+PrintCommandLineFlags

主要可以用来查看默认的垃圾回收器

[root@VM-20-13-centos jenkins]# java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=62077952 -XX:MaxHeapSize=993247232 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
java version "1.8.0_311"
Java(TM) SE Runtime Environment (build 1.8.0_311-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.311-b11, mixed mode)

  目录