Article directory
- 01-JVM parameter option type
- 02-Add JVM parameter option
- 03 Commonly used JVM parameter options
- 04-Get JVM parameters through Java code
01-JVM parameter option type
Type 1: Standard parameter options
features
Relatively stable, and will basically not change in subsequent versions
To ... beginning
various options
Run java or java -help to see all standard options
Supplementary content -server and -client
HotSpot JVM has two modes, namely server and client, respectively through -server and client, respectively through -server and -client mode settings
- On 32-bit Windows systems, the Client type of JVM is used by default. To use the Server mode, the machine must have at least 2 or more CPUs and more than 2G of physical memory. The client mode is suitable for desktop applications with small memory requirements, and the Serial serial garbage collector is used by default.
- Only server-mode JVM is supported on 64-bit machines, suitable for applications that require large memory, and the parallel garbage collector is used by default
The official website introduction about server and client is: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/server-class.html
Type 2: -X parameter option
features
- Unnormalized parameters
- The function is relatively stable. But the official said that subsequent versions may change
- start with -X
various options
Run the java -X command to see all the X options
-Xmixed 混合模式执行 (默认)
-Xint 仅解释模式执行
-Xcomp 仅采用即时编译器模式
-Xbootclasspath:<用 ; 分隔的目录和 zip/jar 文件>
设置搜索路径以引导类和资源
-Xbootclasspath/a:<用 ; 分隔的目录和 zip/jar 文件>
附加在引导类路径末尾
-Xbootclasspath/p:<用 ; 分隔的目录和 zip/jar 文件>
置于引导类路径之前
-Xdiag 显示附加诊断消息
-Xnoclassgc 禁用类垃圾收集
-Xincgc 启用增量垃圾收集
-Xloggc:<file> 将 GC 状态记录在文件中 (带时间戳)
-Xbatch 禁用后台编译
-Xms<size> 设置初始 Java 堆大小
-Xmx<size> 设置最大 Java 堆大小
-Xss<size> 设置 Java 线程堆栈大小
-Xprof 输出 cpu 配置文件数据
-Xfuture 启用最严格的检查, 预期将来的默认值
-Xrs 减少 Java/VM 对操作系统信号的使用 (请参阅文档)
-Xcheck:jni 对 JNI 函数执行其他检查
-Xshare:off 不尝试使用共享类数据
-Xshare:auto 在可能的情况下使用共享类数据 (默认)
-Xshare:on 要求使用共享类数据, 否则将失败。
-XshowSettings 显示所有设置并继续
-XshowSettings:all
显示所有设置并继续
-XshowSettings:vm 显示所有与 vm 相关的设置并继续
-XshowSettings:properties
显示所有属性设置并继续
-XshowSettings:locale
显示所有与区域设置相关的设置并继续
-X 选项是非标准选项,如有更改,恕不另行通知
Options related to JVM compilation mode
-Shint
Only use interpreter: all bytecodes are interpreted and executed, the speed of this mode is very slow
-Xcomp
Compiler only: all bytecodes are converted to native code on first use and then executed
-Xmixed
Mixed mode : This is the default mode. At the beginning, the interpreter is used to explain and execute slowly. Later, the JIT compiler is used to selectively compile and cache some hot codes in advance according to the running conditions of the program. Then the efficiency is very high.
In particular
-Xmx -Xms -Xss are XX parameters?
-Xms sets the initial Java heap size, equivalent to -XX:InitialHeapSize
When viewing and changing parameters, initialHeapSize should be used, such as jinfo flag
-Xmx sets the maximum Java heap size, equivalent to -XX:MaxHeapSize
-Xss sets the Java thread stack size, equivalent to -XX:ThreadStackSize
type three
features
- Unnormalized parameters
- The most used parameter type
- These options are experimental and unstable
- Start with -XX
effect
For developing and debugging the JVM
Classification
Boolean format
-XX: + means to enable the option attribute
-XX:+ means to disable the option attribute
example
-XX: +UseParallelGC selects the garbage collector as a parallel collector
-XX:+UseG1GC means to enable the G1 collector
-XX:+UseAdaptiveSizePolicy automatically selects the size of the young area and the corresponding proportion of the Survivor area
Note: Because some commands are enabled by default, you can use -close
Non-Boolean format (key-value type)
Subtype 1: Numeric Format -XX: =
number represents a value, and number can carry a unit, such as: 'm', 'M'
For example:
-XX:NewSize=1024m means to set the initial size of the new generation to 1024 megabytes
-XX:MaxGCPauseMillis=500 means to set the GC pause time: 200 milliseconds
-XX:GCTimeRatio=19 means set throughput
-XX:NewRatio=2 indicates the ratio of the new generation to the old generation
Subtype 2: non-numeric format -XX: =
For example:
-XX:HeapDumpPath=/usr/local/headdump.hprof is used to specify the storage path of heap dump.
In particular
-XX:+PrintFlagsFinal
- Print the names and default values of all parameters
- The parameters of Diagnostic and Experimental are not included by default
- Can be used with -XX:+UnlockDiagnosticVMOptions and -XX:UnlockExpermentalVMOptions
02-Add JVM parameter option
Run the Jar package
java -Xms50m -Xmx50m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar demo.jar
While the program is running
Use jinfo -flag = to set non-Boolean type parameters
Use jinfo -flag [+|-] to set Boolean type parameters
03 Commonly used JVM parameter options
XX option and value of print setting
options | illustrate |
---|---|
-XX:PrintCommandLineFlags | Allows the program to print out the XX selection manually set by the user or automatically set by the JVM before the program runs |
-XX:+PrintFlagsInitial | Indicates to print out the default value of all XX options |
-XX:+PrintFlagsFinal | Indicates to print out the value that the XX option takes effect when running the program |
-XX:+PrintVMOptions | Print the parameters of the JVM |
Heap, stack, method area and other memory size settings
the stack
options | illustrate |
---|---|
-Xss128k | Equivalent to -XX:ThreadStackSize, set the stack size of each thread to 128k |
heap memory
options | illustrate |
---|---|
-Xms3550m | Equivalent to -XX:InitialHeapSize, set the JVM initial heap memory to 3500M |
-Xmx3550m | Equivalent to -XX:MaxHeapSize, set the maximum heap memory of the JVM to 3500M |
-Xmn2g | Set the size of the young generation to 2G, which is equivalent to -XX:NewSize=2g -XX:MaxNewSize=2g, that is, set the initial value of the young generation and the maximum value of the young generation to be 2G. The official recommended configuration is 3/8 of the entire heap size |
-XX:NewSize=1024m | Set the initial value of the young generation to 1024M |
-XX:MaxNewSize=1024m | Set the maximum value of the young generation to 1024M |
-XX:SurvivorRatio=8 | Set the ratio of the Eden area to a Survivor area in the young generation, the default is 8 |
-XX:+UseAdaptiveSizePolicy | Automatically select the size ratio of each area, which is enabled by default |
-XX:NewRatio=2 | Set the ratio of the old generation to the young generation (including 1 Eden area and 2 Survivor areas), the default is 2 |
-XX:PretenureSizeThreadshold=1024 | Set to allow objects larger than this threshold to be directly allocated in the old generation, the unit is byte only valid for Serial and ParNew collectors |
-XX:MaxTenuringThreshold=15 | The default value is 15. After each MinorGC in the new generation, the age of the surviving objects is +1. When the age of the object is greater than the set value, it enters the old generation |
-XX:+PrintTenuringDistribution | Let the JVM print out the age distribution of objects in Survivor currently in use after each MinorGC |
-XX:TargetSurvivorRatio | Indicates the expected proportion of space occupied in the Survivor area after MinorGC ends |
-XX:SurvivorRatio=8 Description
Only when the ratio of Eden area and Survivor area is explicitly used, the ratio will take effect, otherwise the ratio will be set automatically. As for the reason, please see the explanation in -XX:+UseAdaptiveSizePolicy below, and finally it is recommended to use -XX which is turned on by default :+UseAdaptiveSizePolicy setting, and does not show setting -XX:SurvivorRatio
-XX:+UseAdaptiveSizePolicy Description
1. Analysis
If enabled by default, it will cause the ratio of Eden area and Survivor area to be automatically allocated, so it will also cause our default value -XX:SurvivorRatio=8 to fail, so the real ratio may not be 8, for example, it may be 6, etc. 2. How to set
it The ratio of the Eden area to the Survivor area
-XX:SurvivorRatio=8
shows the ratio of the Eden area to the Survivor area, then use my own
without showing the ratio of the Eden area to the Survivor area, whether it is turned on or off -XX:+UseAdaptiveSizePolicy, The proportion of Eden area and Survivor area will be automatically setConclusion:
Only when the ratio of the Eden area and the Survivor area is displayed, the ratio will take effect, otherwise the ratio will be automatically set. Finally, it is recommended to use the -XX:+UseAdaptiveSizePolicy setting that is turned on by default, and do not display the setting -XX:SurvivorRatio
-XX:NewRatio=2
Set according to the actual situation, mainly according to the object life cycle to allocate, if the object life cycle is very long, then make the old generation bigger, otherwise make the new generation bigger
method area
permanent generation
parameter | illustrate |
---|---|
-XX:PermSize=256m | Set the permanent generation initial value to 256M |
-XX:MaxPermSize=256m | Set the maximum permanent generation to 256M |
Metaspace
parameter | illustrate |
---|---|
-XX:MetaspaceSize | initial space size |
-XX:MaxMetaspaceSize | The maximum space, there is no limit by default |
-XX:+UseCompressedOops | Use compressed object pointers |
-XX:+UseCompressedClassPointers | Using compressed class pointers |
-XX:CompressedClassSpaceSize | Set the size of Klass Metaspace, the default is 1G |
direct memory
parameter | illustrate |
---|---|
-XX:MaxDirectMemorySize | Specify the capacity of DirectMemory, if not specified, the default is the same as the maximum value of the Java heap |
OutOfMemory related options
-XX:+HeapDumpOnOutMemoryError (generate dump file when OOM occurs
) and -XX:+HeapDumpBeforeFullGC (generate dump file when Full GC occurs) can only be set to one
, if not set -XX:HeapDumpPath=, then a dump file will be generated in the current directory, if set, a dump file will be generated in the specified location
parameter | illustrate |
---|---|
-XX:+HeapDumpOnOutMemoryError | 表示在内存出现OOM的时候,生成Heap转储文件,以便后续分析,-XX:+HeapDumpBeforeFullGC和-XX:+HeapDumpOnOutMemoryError只能设置1个 |
-XX:+HeapDumpBeforeFullGC | 表示在出现FullGC之前,生成Heap转储文件,以便后续分析,-XX:+HeapDumpBeforeFullGC和-XX:+HeapDumpOnOutMemoryError只能设置1个,请注意FullGC可能出现多次,那么dump文件也会生成多个 |
-XX:HeapDumpPath=
|
指定heap转存文件的存储路径,如果不指定,就会将dump文件放在当前目录中 |
-XX:OnOutOfMemoryError | 指定一个可行性程序或者脚本的路径,当发生OOM的时候,去执行这个脚本 |
-XX:OnOutOfMemoryError示例:
-XX:OnOutOfMemoryError=/opt/Server/restart.sh
垃圾收集器相关选项
查看默认的垃圾回收器
- -XX:+PrintCommandLineFlags查看命令行相关参数(包含使用的垃圾收集器)
- 使用命令行指令:jinfo -flag 相关垃圾回收器参数 进程ID
以上两种方式都可以查看默认使用的垃圾回收器,第一种方式需要程序的支持;第二种方式需要去尝试,如果使用了返回值中有+号,否则就是-号。
Serial回收器
Serial收集器作为HotSpot中Client模式下的默认新生代垃圾收集器。Serial Old是运行在Client模式下默认的老年代的垃圾收集器。
-XX:UseSerialGC
指定年轻代和老年代都使用串行收集器。等价于:新生代用Serial GC,且老年代用Serial Old GC。可以获得最高的单线程收集效率。
Parnew回收器
-XX:+UseParNewGC
手动指定使用ParNew收集器执行内存回收任务。它表示年轻代使用并行收集器,不影响老年代。
-XX:ParallerlGCThreads设置年轻代并行收集器的线程数。一般地,最好与CPU数量相等,以避免过多的线程数影响垃圾收集性能。
- 在默认情况下,当CPU数量小于8时,ParallelGCThreads的值等于CPU数量。
- 在CPU数量大于8个,ParallelGCThreads的值等于3+[5 * CPU_Count] / 8
Parallel回收器
-XX:+UseParallelGC 手动指定年轻代使用Parallel并行收集器执行垃圾回收任务。
-XX:+UseParallelOldGC 手动指定老年代都是使用并行回收收集器
分别适用于新生代和老年代。默认jdk8是开启的。
- 分别适用于新生代和老年代。默认jdk8是开启的。
- 上面两个参数,默认开启一个,另一个也会被开启。(互相激活)
-XX:ParallelGCThreads 设置年轻代并行收集器的线程数。一般地,最好与CPU数量相等,以避免线程数过多影响垃圾收集性能。
- 在默认情况下,当CPU数量小于8个,ParallelGCThreads的值等于CPU数量。
- 当CPU数量大于8个,ParellelGCThreads的值等于3+[5*CPU_Count]/8。
-XX:MaxGCPauseMillis设置垃圾回收器的最大停顿时间(即STW的时间)。单位是毫秒。
- 为了尽可能地把停顿时间控制在MaxGCPauseMillis以内,收集器会在工作时调整Java堆的大小或者一些其他的参数。
- 对于用户来讲,停顿时间越短体验越好。但是在服务器短,我们注重高并发,整体的吞吐量。所以服务器端适合Parallel,进行控制。
- 该参数使用需谨慎。
-XX:GCTimeRatio 垃圾收集器时间占总运行时间的比例(=1 / (X+1))。用于衡量吞吐量大小。
- 取值范围(0,100)。默认99,也就是垃圾回收时间不超多1%。
- 与前一个-XX:MaxGCPauseMillis参数有一定的矛盾性。暂停时间越长,Radio参数就越容易超过设定的比例。
-XX:+UseAdaptiveSizePolicy 设置Parallel Scavenge收集器具有自适应调节策略
- 在这种模式下,年轻代的大小、Eden和Survivor的比例、晋升老年代的对象年龄等参数会被自动调整,已达到在堆大小、吞吐量和停顿时间之间的平衡点。
- 在手动调优比较困难的场合,可以直接使用这种自适应的方式,仅指定虚拟机的最大堆、目标的吞吐量(GCTimeRatio)和停顿时间(MaxGCPauseMillis),让虚拟机自己完成调优工作。
注意:
- Parallel回收器主打吞吐量,而CMS和G1主打低延迟,如果主打吞吐量,那么就不应该限制最大停顿时间,所以-XX:MaxGCPauseMills不应该设置
- -XX:MaxGCPauseMills中的调整堆大小通过默认开启的-XX:+UseAdaptiveSizePolicy来实现
- -XX:GCTimeRatio用来衡量吞吐量,并且和-XX:MaxGCPauseMills矛盾,因此不会同时使用
CMS回收器
-XX:+UseConcMarkSweepGC 手动指定使用CMS收集器执行内存回收任务。
- 开启该参数后会自动将-XX:+UseParkNewGC打开。即ParNew(Young区用)+CMS(Old区用)+Serial Old的组合。
–XX:CMSInitiatingOccupanyFraction设置堆内存使用率的阈值,一旦达到该阈值,便开始进行回收。
- JDK5及以前版本的默认值为68,即当老年代的空间使用率达到68%时,会执行一次CMS回收。JDK6及以上版本默认值为92%。
- 如果内存增长缓慢,可以设置一个稍大的值,大的阈值可以有效降低CMS的触发频率,减少老年代回收的次数可以较为明显的改善应用程序性能。反之,如果应用程序内存使用率增长很快,则应该降低这个阈值,以避免频繁触发老年代的串行收集器。因此通过该选项可以有效降低Full GC的执行次数。
–XX:+UseCMSCompactAtFullGollection 用于指定在执行完Full GC后对内存空间进行压缩整理,以此避免内存对象的产生。不过由于内存压缩整理过程无法并发执行,所带来的问题就是停顿时间变得更长了。
–XX:CMSFullGCsBeforeCompaction 设置在执行多少次Full GC后对内存空间进行压缩整理。
–XX:ParallelCMSThreads 设置CMS线程数量。
- CMS默认启动的线程数是(ParallelGCThreads+3)/4 ,ParallelGCThreads是年轻代并行收集器的线程数。当CPU资源比较紧张时,受到CMS收集器线程的影响,应用程序的性能在垃圾回收阶段可能会非常糟糕。
特别参数:
特别说明:
- JDK9新特性:CMS被标记Deprecate了(JEP291)
- 如果对JDK 9及以上版本的HotSpot虚拟机使用参数-XX:+UseConcMarkSweepGC来开启CMS收集器的话,用户会收到一个警告信息,提示CMS未来将会被废弃
- JDK 14新特性:删除CMS垃圾回收器(JEP363)
- 溢出了CMS垃圾收集器,如果在JDK14中使用-XX:+UseConcMarkSweepGC的话,JVM不会报错,只是给一个warning信息,但是不会exit。JVM会自动回退以默认GC方式启动JVM
G1回收器
-XX:+UseG1GC
- 手动指定使用G1收集器执行内存回收任务。
-XX:G1HeapRegionSize
- 设置每个Region的大小。值是2的幂,范围是1MB到32MB之间,目标是根据最小的Java堆大小划分出2048个区域。默认是堆内存的1/2000。
-XX:MaxGCPauseMillis:
- 设置期望达到的最大GC停顿时间指标(JVM会尽力实现,但不保证达到)。默认值是200ms
-XX:ParallelGCThread
- 设置STW时GC线程数的值。最多设置为8
-XX:ConcGCThreads
- 设置并发标记的线程数。将n设置为并行垃圾回收线程数(ParallelGCThreads)的四分之一左右。
-XX:InitiatingHeapOccupancyPercent
- 设置触发并发周期的Java堆占用率。超过此值,就触发GC。默认值是45。
-XX:G1NewSizePercent、-XX:G1MaxNewSizePercent
- 新生代占用整个堆内存的最小百分比(默认5%)、最大百分比(默认60%)
-XX:G1ReservePersent=10
- 保留内存区域,防止 to space(Survivor中的to区)溢出。
如果使用G1垃圾收集器,不建议设置-Xmn和-XX:NewRatio,毕竟可能影响G1的自动调节
怎么选择垃圾收集器
- 有限调整堆的小让JVM自适应完成。
- 如果内存小于100M,使用串行收集器
- 如果是单核、单机程序,并且没有停顿时间的要求,串行收集器
- 如果是多CPU、需要高吞吐量、允许停顿时间超过1秒,选择并行或者JVM自己选择
- 如果是多CPU、追求低停顿时间,需要快速响应(比如延迟不能超过1秒,如互联网应用),使用并发收集器。官方推荐G1,性能高。现在互联网的项目,基本都是使用G1
特别说明:
- 没有最好的收集器,更没有万能的收集;
- 调优永远是针对特定场景、特定需求,不存在一劳永逸的收集器
GC日志相关选项
常用参数
参数 | 说明 | 是否可以独立使用 |
---|---|---|
-verbose:gc | 输出日志信息,默认输出的标准输出 | 是 |
-XX:+PrintGC | 等同于-verbose:gc 表示打开简化的日志 |
是 |
-XX:+PrintGCDetails | 在发生垃圾回收时打印内存回收详细的日志, 并在进程退出时输出当前内存各区域的分配情况 |
是 |
-XX:+PrintGCTimeStamps | 程序启动到GC发生的时间秒数 | 不可以独立使用,需要配合-XX:+PrintGCDetails使用 |
-XX:+PrintGCDateStamps | 输出GC发生时的时间戳(以日期的形式,例如:2013-05-04T21:53:59.234+0800) | 不可以独立使用,可以配合-XX:+PrintGCDetails使用 |
-XX:+PrintHeapAtGC | 每一次GC前和GC后,都打印堆信息 | 是 |
-XIoggc: | 把GC日志写入到一个文件中去,而不是打印到标准输出中 | 是 |
其他参数
参数 | 说明 |
---|---|
-XX:TraceClassLoading | 监控类的加载 |
-XX:PrintGCApplicationStoppedTime | 打印GC时线程的停顿时间 |
-XX:+PrintGCApplicationConcurrentTime | 垃圾收集之前打印出应用未中断的执行时间 |
-XX:+PrintReferenceGC | 记录回收了多少种不同引用类型的引用 |
-XX:+PrintTenuringDistribution | 让JVM在每次MinorGC后打印出当前使用的Survivor中对象的年龄分布 |
-XX:+UseGCLogFileRotation | 启用GC日志文件的自动转储 |
-XX:NumberOfGCLogFiles=1 | GC日志文件的循环数目 |
-XX:GCLogFileSize=1M | 控制GC日志文件的大小 |
其他参数
参数 | 说明 |
---|---|
-XX:+DisableExplicitGC | 禁用hotspot执行System.gc(),默认禁用 |
-XX:ReservedCodeCacheSize=[g、m、k] -XX:InitialCodeCacheSize=[g、m、k] |
指定代码缓存的大小 |
-XX:+UseCodeCacheFlushing | 使用该参数让jvm放弃一些被编译的代码, 避免代码缓存被占满时JVM切换到interpreted-only的情况 |
-XX:+DoEscapeAnalysis | 开启逃逸分析 |
-XX:+UseBiasedLocking | 开启偏向锁 |
-XX:+UseLargePages | 开启使用大页面 |
-XX:+PrintTLAB | 打印TLAB的使用情况 |
-XX:TLABSize | 设置TLAB大小 |
04-通过Java代码获取JVM参数
Java提供了java.lang.management包用于监视和管理Java虚拟机和Java运行时中的其他组件,它允许本地和远程监控和管理运行的Java虚拟机。其中managementFactory这个类还是挺常用的。另外还有Runtime类也可以获取一些内存、CPU核数等相关的数据。
通过这些api可以监控我们的应用服务器的堆内存使用情况,设置一些阈值进行报警等处理。
public class MemoryMonitor {
public static void main(String[] args) {
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
MemoryUsage usage = memoryMXBean.getHeapMemoryUsage();
System.out.println("INIT HEAP: " + usage.getInit() / 1024 / 1024 + "m");
System.out.println("MAX HEAP: " + usage.getMax() / 1024 / 1024 + "m");
System.out.println("USE HEAP: " + usage.getUsed() / 1024 / 1024 + "m");
System.out.println("\nFull Information:");
System.out.println("Heap Memory Usage: " + memoryMXBean.getHeapMemoryUsage());
System.out.println("Non-Heap Memory Usage: " + memoryMXBean.getNonHeapMemoryUsage());
System.out.println("=======================通过java来获取相关系统状态============================ ");
System.out.println("当前堆内存大小totalMemory " + (int) Runtime.getRuntime().totalMemory() / 1024 / 1024 + "m");// 当前堆内存大小
System.out.println("空闲堆内存大小freeMemory " + (int) Runtime.getRuntime().freeMemory() / 1024 / 1024 + "m");// 空闲堆内存大小
System.out.println("最大可用总堆内存maxMemory " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "m");// 最大可用总堆内存大小
}
}