Part II of JVM: Performance Monitoring and Tuning_04_JVM Runtime Parameters_Silicon Valley

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

  1. 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.
  2. 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 set

Conclusion:
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

垃圾收集器相关选项

image-20221016141429824

image-20221016141435819

查看默认的垃圾回收器

  • -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收集器线程的影响,应用程序的性能在垃圾回收阶段可能会非常糟糕。

特别参数:

image-20221016144911110

特别说明:

  • 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

特别说明:

  1. 没有最好的收集器,更没有万能的收集;
  2. 调优永远是针对特定场景、特定需求,不存在一劳永逸的收集器

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");// 最大可用总堆内存大小
    }
}

Guess you like

Origin blog.csdn.net/weixin_43811294/article/details/127348131