当前位置: 首页 > article >正文

JVM 性能调优 - 参数基础(2)

查看 JDK 版本

$ java -version
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

查看 Java 帮助文档

$ java -help
用法: java [-options] class [args...]
           (执行类)
   或  java [-options] -jar jarfile [args...]
           (执行 jar 文件)
其中选项包括:
    -d32          使用 32 位数据模型 (如果可用)
    -d64          使用 64 位数据模型 (如果可用)
    -server       选择 "server" VM
                  默认 VM 是 server.

    -cp <目录和 zip/jar 文件的类搜索路径>
    -classpath <目录和 zip/jar 文件的类搜索路径>
                  用 ; 分隔的目录, JAR 档案
                  和 ZIP 档案列表, 用于搜索类文件。
    -D<名称>=<值>
    -ea[:<packagename>...|:<classname>]
    -enableassertions[:<packagename>...|:<classname>]
                  按指定的粒度启用断言
    -da[:<packagename>...|:<classname>]
    -disableassertions[:<packagename>...|:<classname>]
                  禁用具有指定粒度的断言
    -esa | -enablesystemassertions
                  启用系统断言
    -dsa | -disablesystemassertions
                  禁用系统断言
    -agentlib:<libname>[=<选项>]
                  加载本机代理库 <libname>, 例如 -agentlib:hprof
                  另请参阅 -agentlib:jdwp=help 和 -agentlib:hprof=help
    -agentpath:<pathname>[=<选项>]
                  按完整路径名加载本机代理库
    -javaagent:<jarpath>[=<选项>]
                  加载 Java 编程语言代理, 请参阅 java.lang.instrument
    -splash:<imagepath>
                  使用指定的图像显示启动屏幕
有关详细信息, 请参阅 http://www.oracle.com/technetwork/java/javase/documentation/index.html。

查看 JDK 版本和帮助文档

$ java -showversion
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)           
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

用法: java [-options] class [args...]          
           (执行类)                            
   或  java [-options] -jar jarfile [args...]  
           (执行 jar 文件)                     
其中选项包括:                                  
    -d32          使用 32 位数据模型 (如果可用)
    -d64          使用 64 位数据模型 (如果可用)
    -server       选择 "server" VM             
                  默认 VM 是 server.           

    -cp <目录和 zip/jar 文件的类搜索路径>
    -classpath <目录和 zip/jar 文件的类搜索路径>
                  用 ; 分隔的目录, JAR 档案
                  和 ZIP 档案列表, 用于搜索类文件。
    -D<名称>=<值>
                  设置系统属性
    -verbose:[class|gc|jni]
                  启用详细输出
    -version      输出产品版本并退出
    -version:<值>
                  警告: 此功能已过时, 将在
                  未来发行版中删除。
                  需要指定的版本才能运行
    -showversion  输出产品版本并继续
    -jre-restrict-search | -no-jre-restrict-search
                  警告: 此功能已过时, 将在
                  未来发行版中删除。
                  在版本搜索中包括/排除用户专用 JRE
    -? -help      输出此帮助消息
    -X            输出非标准选项的帮助
    -ea[:<packagename>...|:<classname>]
    -enableassertions[:<packagename>...|:<classname>]
                  按指定的粒度启用断言
    -da[:<packagename>...|:<classname>]
    -disableassertions[:<packagename>...|:<classname>]
                  禁用具有指定粒度的断言
    -esa | -enablesystemassertions
                  启用系统断言
    -dsa | -disablesystemassertions
                  禁用系统断言
    -agentlib:<libname>[=<选项>]
                  加载本机代理库 <libname>, 例如 -agentlib:hprof
                  另请参阅 -agentlib:jdwp=help 和 -agentlib:hprof=help
    -agentpath:<pathname>[=<选项>]
                  按完整路径名加载本机代理库
    -javaagent:<jarpath>[=<选项>]
                  加载 Java 编程语言代理, 请参阅 java.lang.instrument
    -splash:<imagepath>
                  使用指定的图像显示启动屏幕
有关详细信息, 请参阅 http://www.oracle.com/technetwork/java/javase/documentation/index.html。

JVM 参数规则

当我们运行一个 java 程序的时候,通常都是 java -jar xxx.jar 的命令,也会根据实际情况配置一些运营参数

$ ps -ef | grep 2144945
root     2144945       1  0 Jan15 ?        01:44:21 /usr/lib/jvm/jre-1.8.0-openjdk-1.8.0.312.b07-2.el8_5.x86_64/bin/java -Dproc_nodemanager -Djava.net.preferIPv4Stack=true -Dsun.security.krb5.debug=true -Dsun.security.spnego.debug -Djava.library.path=/opt/hadoop/lib/native -Dcom.sun.management.jmxremote.port=7774 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -XX:+UseParallelGC -Dyarn.log.dir=/opt/hadoop/logs -Dyarn.log.file=hadoop-root-nodemanager-LOCAL-VM-337.log -Dyarn.home.dir=/opt/hadoop -Dyarn.root.logger=INFO,console -Dhadoop.log.dir=/opt/hadoop/logs -Dhadoop.log.file=hadoop-root-nodemanager-LOCAL-VM-337.log -Dhadoop.home.dir=/opt/hadoop -Dhadoop.id.str=root -Dhadoop.root.logger=INFO,RFA -Dhadoop.policy.file=hadoop-policy.xml -Dhadoop.security.logger=INFO,NullAppender org.apache.hadoop.yarn.server.nodemanager.NodeManager

这些参数可以分为四类:

  • 以 - 开头的标准参数。所有 JVM 都支持,且向后兼容。

如 -verbose:gc、-server

  • 以 -X 开头的非标准参数,绝大多数都是用于控制 JVM 的参数。

如 -Xmx2G、-Xms2G

  • 以 -XX 开头的非稳定参数,专门用于控制 JVM 行为的参数。

如 -XX:PrintGCDetails、-XX:+UseParNewGC

  • 以 -D 开头的系统参数(也可以是自定义参数),在程序中可以通过 System.setProperty(key, value) 进行设置,以及通过 System.getProperty(key) 进行获取。

如 -Dfile.encoding=UTF-8、-Dlog.path=/data/log/

下面我们主要介绍 -X 和 -XX 参数。

-X 非标准参数的使用

在这里,先简单介绍下 JVM 常用的编译模式:

  1. 解释模式(Interpreted Mode):在解释模式下,JVM会逐行解释Java字节码并执行。这种模式下的代码执行速度较慢,因为每次执行都需要解释字节码。

  2. 即时编译模式(Just-In-Time Compilation Mode,JIT):在即时编译模式下,JVM会将热点代码(经常执行的代码)编译成本地机器代码,以提高执行速度。JIT编译器会根据运行时的性能数据进行优化,以提高代码的执行效率。

  3. 混合模式(Mixed Mode):混合模式是解释模式和即时编译模式的结合。在初始阶段,JVM会使用解释模式执行代码,同时收集运行时的性能数据。当代码被判定为热点代码时,JVM会将其编译成本地机器代码,并在后续执行中使用即时编译模式。

  4. AOT编译模式(Ahead-Of-Time Compilation Mode):AOT编译模式是在应用程序部署之前将Java字节码编译成本地机器代码。这种模式可以提高应用程序的启动速度和整体性能,但会增加部署和维护的复杂性。

下面,我们通过 java -version 命令查看 JDK 版本信息

通过截图可知,我们的编译模式为 mixed mode(混合模式,默认)。

修改编译模式为解释执行模式:

修改编译模式为编译模式:

修改编译模式为混合模式:

对于不同编译模式的耗时情况,可以通过以下实验进行验证

package com.test;

public class TestCompileMode {
    public static void main(String[] args) {
        Long start = System.currentTimeMillis();
        for(int i =0; i < 100000; i++) {
        }
        Long end = System.currentTimeMillis();
        System.out.println("cost: " + (end - start) + " ms");
    }
}

$ java -Xint com.test.TestCompileMode
cost: 1 ms

$ java -Xcomp com.test.TestCompileMode
cost: 3 ms

$ java -Xmixed com.test.TestCompileMode
cost: 0 ms

-XX 非稳定参数的使用

查看 XX 配置项所有参数及其默认值

$ java -XX:+PrintFlagsInitial | head -n 10
[Global flags]
    uintx AdaptiveSizeDecrementScaleFactor          = 4                                   {product}
    uintx AdaptiveSizeMajorGCDecayTimeScale         = 10                                  {product}
    uintx AdaptiveSizePausePolicy                   = 0                                   {product}
    uintx AdaptiveSizePolicyCollectionCostMargin    = 50                                  {product}
    uintx AdaptiveSizePolicyInitializingSteps       = 20                                  {product}
    uintx AdaptiveSizePolicyOutputInterval          = 0                                   {product}
    uintx AdaptiveSizePolicyWeight                  = 10                                  {product}
    uintx AdaptiveSizeThroughPutPolicy              = 0                                   {product}
    uintx AdaptiveTimeWeight                        = 25                                  {product}

由于非State参数非常的多,因此这里就不列出所有参数进行讲解。只介绍我们比较常用的。

Java HotSpot VM 中 -XX 的按照功能可以被松散的聚合成三类:

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

行为参数(功能开关)

-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    启用本地线程优先级 

性能调优

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

调试参数

-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 跟踪类加载器约束的相关信息

XX 参数的使用有两种类型,一种是 Boolean 类型,另外一种是键值对类型。

  • Boolean 类型。
    • -XX:+某个属性 或者,-XX:-某个属性。 + 表示开启了这个属性,- 表示关闭了这个属性。
    • 案例:-XX:-PrintGCDetails,表示关闭了 GC 详情输出。同理,-XX:+PrintGCDetails,表示开启了GC详情输出
  • key-value 类型。
    • -XX: key=value。
    • 案例:-XX: MetaspaceSize=20000,设置 Java 元空间的值为 20000。

查看程序是否开启了某个参数

package com.test;

public class TestCompileMode {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Hello, World!");
        Thread.sleep(Integer.MAX_VALUE);
    }
}

【关闭验证】

运行 TestCompileMode

java com.test.TestCompileMode

使用 jps(Java Virtual Machine Process Status Tool) 命令查看进程ID

$ jps -l
27392 org.jetbrains.idea.maven.server.RemoteMavenServer
17240
22088 sun.tools.jps.Jps
21740 org.jetbrains.idea.maven.server.RemoteMavenServer
25548 com.test.TestCompileMode

查看程序是否开启了 PrintGCDetails 参数

$ jinfo -flag PrintGCDetails 25548
-XX:-PrintGCDetails

- 没有关闭,故程序没有开启 PrintGCDetails

【开启验证】

运行 TestCompileMode

java -XX:+PrintGCDetails com.test.TestCompileMode

使用 jps(Java Virtual Machine Process Status Tool) 命令查看进程ID

$ jps -l
27392 org.jetbrains.idea.maven.server.RemoteMavenServer
23444 com.test.TestCompileMode
17240
25768 sun.tools.jps.Jps
21740 org.jetbrains.idea.maven.server.RemoteMavenServer

查看程序是否开启了 PrintGCDetails 参数

$ jinfo -flag PrintGCDetails 23444
-XX:+PrintGCDetails

+ 表示开启,故程序开启了 PrintGCDetails

查看元数据空间值

package com.test;

public class TestCompileMode {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Hello, World!");
        Thread.sleep(Integer.MAX_VALUE);
    }
}

运行 TestCompileMode

 java com.test.TestCompileMode

查看程序的元数据空间值

$ jps -l
27392 org.jetbrains.idea.maven.server.RemoteMavenServer
23444 com.test.TestCompileMode
17240
25768 sun.tools.jps.Jps
21740 org.jetbrains.idea.maven.server.RemoteMavenServer

$ jinfo -flag MetaspaceSize 23444
-XX:MetaspaceSize=21807104

设置元数据空间值

java -XX:MetaspaceSize=100m com.test.TestCompileMode

设置堆内内存大小

$ java -XX:InitialHeapSize=50m -XX:MaxHeapSize=100m com.test.TestCompileMode

或者

$ java -Xms50m -Xmx100m com.test.TestCompileMode

默认情况下 -Xms 初始化堆内存为物理内存的 1/64 ,最大堆内存为物理内存 1/4。

查看堆内存参数 

$ jps -l
25920 sun.tools.jps.Jps
27392 org.jetbrains.idea.maven.server.RemoteMavenServer
30532 com.test.TestCompileMode
17240 
21740 org.jetbrains.idea.maven.server.RemoteMavenServer
26748 org.jetbrains.jps.cmdline.Launcher

$ jinfo -flag InitialHeapSize 30532
-XX:InitialHeapSize=52428800

$ jinfo -flag MaxHeapSize 30532
-XX:MaxHeapSize=104857600

查看程序的所有参数值

$ jps -l
27392 org.jetbrains.idea.maven.server.RemoteMavenServer
2804 sun.tools.jps.Jps
30452 com.test.TestCompileMode
17240 
21740 org.jetbrains.idea.maven.server.RemoteMavenServer

$ jinfo -flags 30452
Attaching to process ID 30452, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.151-b12
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=52428800 -XX:MaxHeapSize=104857600 -XX:MaxNewSize=34603008 -XX:MinHe
apDeltaBytes=524288 -XX:NewSize=17301504 -XX:OldSize=35127296 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUno
rderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line:  -Xms50m -Xmx100m

  • Non-Default:表示该参数的值已经被用户手动设置,而不是使用默认值。这意味着该参数的值是通过命令行选项、环境变量或其他方式显式设置的,而不是使用JVM的默认配置。

  • Command Line Flag:表示该参数是通过命令行选项来设置的。

查看 JVM 当前所有 XX 配置项

$ java -XX:+PrintFlagsFinal -version | head -n 10
[Global flags]
    uintx AdaptiveSizeDecrementScaleFactor          = 4                                   {product}
    uintx AdaptiveSizeMajorGCDecayTimeScale         = 10                                  {product}
    uintx AdaptiveSizePausePolicy                   = 0                                   {product}
    uintx AdaptiveSizePolicyCollectionCostMargin    = 50                                  {product}
    uintx AdaptiveSizePolicyInitializingSteps       = 20                                  {product}
    uintx AdaptiveSizePolicyOutputInterval          = 0                                   {product}
    uintx AdaptiveSizePolicyWeight                  = 10                                  {product}
    uintx AdaptiveSizeThroughPutPolicy              = 0                                   {product}
    uintx AdaptiveTimeWeight                        = 25                                  {product}
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

Global flags:全局参数,如果自定义修改了某个应用的参数,并不会修改全局参数。

查看 InitialHeapSize 默认值和当前配置的值

$ java -XX:+PrintFlagsInitial -version | grep InitialHeapSize
    uintx InitialHeapSize                           = 0                                   {product}

$ java -XX:+PrintFlagsFinal -version | grep InitialHeapSize
    uintx InitialHeapSize                          := 400556032                           {product}
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

查看 MaxHeapSize 默认值和当前配置的值

$ java -XX:+PrintFlagsInitial -version | grep MaxHeapSize
    uintx MaxHeapSize                               = 130862280                           {product}

$ java -XX:+PrintFlagsFinal -version | grep MaxHeapSize
    uintx MaxHeapSize                              := 2111832064                          {product}
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
 

查看 JVM 自动配置的或者用户手动设置的 XX 选项(非应用程序的)

$ java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=400412928 -XX:MaxHeapSize=6406606848 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompresse
dOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

如果您觉得文章对您有帮助,欢迎留言打赏,感谢您的支持! 


http://www.kler.cn/a/231872.html

相关文章:

  • 杰控通过 OPCproxy 获取数据发送到服务器
  • 【Android】EventBus事件总线用法浅析
  • 【STM32】USB 简要驱动软件架构图
  • Jenkins下载安装、构建部署到linux远程启动运行
  • ASP.NET 部署到IIS,访问其它服务器的共享文件 密码设定
  • HOW - PPT 制作系列(一)
  • Java实现批量视频抽帧2.0
  • 前端架构: 脚手架的开发流程和常用框架
  • 基于“python+”潮汐、风驱动循环、风暴潮等海洋水动力模拟实践技术
  • macOS系统下彻底删除应用程序和其数据、配置等
  • 《Git 简易速速上手小册》第1章:Git 基础(2024 最新版)
  • Python进阶----在线翻译器(Python3的百度翻译爬虫)
  • get通过发送Body传参-工具类
  • Go 语言中如何大小端字节序?int 转 byte 是如何进行的?
  • 小白水平理解面试经典题目LeetCode 21. Merge Two Sorted Lists【Linked List类】
  • 【Web - 框架 - Vue】随笔 - 通过`CDN`的方式使用`VUE 2.0`和`Element UI`
  • CDN相关和HTTP代理
  • nodejs将console.log保存到log.txt文档中(electron工具)
  • 图像处理入门:OpenCV的基础用法解析
  • 09 AB 10串口通信发送原理
  • SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式 基础(持续更新~)
  • PdfFactory Pro软件下载以及序列号注册码生成器
  • 总结-回想2023
  • Java图形化界面编程——Container容器 笔记
  • Netty的常用组件及线程模型设计(二)
  • Markdown:简洁高效的文本标记语言