JVM运行参数
一、按照规范范围区分
根据规范范围区分(也就是规范的是所有虚拟机、还是指定一款虚拟机、还是指定一款虚拟机的指定版本),JVM的参数主要分为三类:标准参数、-X非标准参数、-XX参数。
以 - 开头为标准参数,所有的 JVM 都要实现这些参数,并且向后兼容,例如下面示例的-server。
-D 设置系统属性,这和在JAVA_HOME中设置是一样的效果,如果都设置了,命令行会覆盖掉JAVA_HOME中的配置。
以 -X 开头为非标准参数, 基本都是传给 JVM 的,默认 JVM 实现这些参数的功能,但是并不保证所有 JVM 实现都满足,且不保证向后兼容。 可以使用 java -X 命令来查看当前 JVM 支持的非标准参数。
以 –XX:开头为非稳定参数, 专门用于控制 JVM的行为,跟具体的 JVM 实现有关,随时可能会在下个版本取消,一般有布尔和具体取值两种方式:
-XX:+-Flags 形式, +- 是对布尔值进行开关。
-XX:key=value 形式, 指定某个选项的值,例如阈值为100ms等。
-server -Dfile.encoding=UTF-8 -Xmx8g -XX:+UseG1GC -XX:MaxPermSize=256m
(一)标准参数
JVM的标准参数是非常稳定的,基本上在后续的版本中都不会改变这些参数,可以使用java -help查看所有的标准参数
C:\Users\licl81>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<名称>=<值>
设置系统属性
-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。
在输出的标准参数中有-version(查看版本)、-showversion(查看版本并继续)、-D(初始化配置参数)等
例如编写以下代码:
public class JavaTest {
public static void main(String[] args) {
String s = System.getProperty("strKey");
s = s == null ? "" : s;
System.out.println("strKey=========================" + s);
}
}
使用javac进行编译,并使用java运行(如果出现使用java运行时报无法加载主类的情况,可以看下这篇文章:https://www.cnblogs.com/wangxiaoha/p/6293340.html)
C:\Users\licl81>javac JavaTest.java
C:\Users\licl81>java JavaTest
strKey=========================
然后开始验证上面的参数,可以使用-version查看版本
C:\Users\licl81>java -version
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)
使用-D设置参数
C:\Users\licl81>java -DstrKey=123abc JavaTest
strKey=========================123abc
使用-showversion查看版本并做其他事情
C:\Users\licl81>java -showversion -DstrKey=123 JavaTest
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)
strKey=========================123
使用-client或-server设置JVM运行方式
C:\Users\licl81>java -showversion -DstrKey=123 -server JavaTest
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)
strKey=========================123
(二)-X非标准参数
JVM的-X参数是非标准的参数,在不同版本的JVM中,参数会有所不同,可以通过java -X来查看参数
C:\Users\licl81>java -X
-Xmixed 混合模式执行(默认)
-Xint 仅解释模式执行
-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:system
(仅限 Linux)显示系统或容器
配置并继续
-XshowSettings:all
显示所有设置并继续
-XshowSettings:vm 显示所有与 vm 相关的设置并继续
-XshowSettings:properties
显示所有属性设置并继续
-XshowSettings:locale
显示所有与区域设置相关的设置并继续
-X 选项是非标准选项。如有更改,恕不另行通知。
在里面挑选几个比较重要的进行说明:
-Xinit、-Xcomp、-Xmixed:
在解释执行模式下,-Xint会强制JVM执行所有的字节码,这样会降低运行速度;也就是强制使用解释模式
-Xcomp与-Xint相反,JVM会在第一次使用时将所有的字节码编译成本地代码,从而带来最大程度的优化(然而很多应用在使用-Xcomp也会有一些性能损失,当然这个损失对比-Xint会小很多,因为-Xcomp并没有让JVM启动所JIT编译器的所有功能,JIT编译器会对是否需要编译做判断,对于只执行少数次数的代码不会进行编译);也就是强制使用编译模式
-Xmixed:混合模式,将解释执行和编译执行进行混合使用,由jvm自己决定使用哪种方式。这也是JVM默认的、推荐的方式。
使用如下,这里需要说明一下,在第一次使用时-Xcomp方式会比-Xint方式慢一点
C:\Users\licl81>java -showversion -Xint JavaTest
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, interpreted mode)
strKey=========================
C:\Users\licl81>java -showversion -Xcomp JavaTest
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, compiled mode)
strKey=========================
C:\Users\licl81>java -showversion -Xmixed JavaTest
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)
strKey=========================
-Xsm和-Xsx参数:
-Xsm和-Xsx分别用来设置堆的初始值和最大值。-Xsm:2048m等价于XX:InitialHeapSize,-Xsx:2048m等价于XX:MaxHeapSize
(三)-XX参数
-XX也是非标准参数,用来对JVM调优和debug操作。
-XX的参数有两种,一种是boolean类型,格式:-XX:[+-],例如-XX:+DisableexplicitGC,用来禁止手动调用System.gc()操作;一种是非boolean类型,格式:-X,例如-XX:NewRatio=1,表示新生代和老年代的比值。
C:\Users\licl81>java -showversion -XX:+DisableExplicitGC JavaTest
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)
strKey=========================
C:\Users\licl81>java -showversion -XX:NewRatio=1 JavaTest
java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)
strKey=========================
(四)查看JVM运行参数
有些时候我们需要查看jvm的运行参数,这个需求一般有两种情况,在启动的时候查看和查看运行中的JVM参数
1、启动时查看JVM参数
C:\Users\licl81>java -XX:+PrintFlagsFinal JavaTest
[Global flags]
intx ActiveProcessorCount = -1 {product}
uintx AdaptiveSizeDecrementScaleFactor = 4 {product}
......
strKey=========================
2、查看运行中的JVM参数
如果想要查看运行中的JVM参数,就需要使用jinfo命令进行查看了;
首先使用 jps 命令查看正在运行的java进程,也可以使用 jps -l 来查看详情
C:\Users\licl81>jps
20960 StatisticsApplication
14292 Launcher
11256 Jps
12760
C:\Users\licl81>jps -l
20960 com.taikang.tkpo2o.statistics.StatisticsApplication
29664 sun.tools.jps.Jps
14292 org.jetbrains.jps.cmdline.Launcher
12760
然后使用jinfo命令查看指定java进程的JVM参数,也可以查看指定参数
C:\Users\licl81>jinfo -flags 20960
Attaching to process ID 20960, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.281-b09
Non-default VM flags: -XX:-BytecodeVerificationLocal -XX:-BytecodeVerificationRemote -XX:CICompilerCount=4 -XX:CompileThreshold=3000 -XX:InitialHeapSize=130023424 -XX:+ManagementServer -XX:MaxHeapSize=2065694720 -XX:MaxNewSize=688390144 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=42991616 -XX:OldSize=87031808 -XX:TieredStopAtLevel=1 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line: -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:53976,suspend=y,server=n -XX:CompileThreshold=3000 -XX:TieredStopAtLevel=1 -Xverify:none -Dspring.output.ansi.enabled=always -javaagent:C:\Users\licl81\AppData\Local\JetBrains\IntelliJIdea2021.1\captureAgent\debugger-agent.jar -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dfile.encoding=UTF-8
C:\Users\licl81>jinfo -flag MaxHeapSize 20960
-XX:MaxHeapSize=2065694720
二、按照参数作用分类
按照作用分类,可以分为系统属性参数、运行模式参数、堆内存设置参数、GC设置参数、分析诊断参数、JavaAgent参数。
(一)系统属性参数
主要是给系统传递一些系统变量和系统内需要使用的一些开关或者数值。
属性参数可以使用多种方式配置,例如:
直接在所在主机上配置环境变量,这种方式会影响所有应用。
在命令行使用 -D 配置,这种方式只会影响当前程序
在Java代码中使用System.setProperty的方式设置。
如果是在linux操作系统上,还可以通过 a=A100 java XXX 来设置
(二)运行模式参数
1、-server:设置 JVM 使用 server 模式,特点是启动速度比较慢,但运行时性能和内存管理效率很高,适用于生产环境。在具有 64 位能力的 JDK 环境下将默认启用该模式,而忽略 -client 参数。
2、-client :JDK1.7 之前在32位的 x86 机器上的默认值是 -client 选项。设置 JVM 使用 client 模式,特点是启动速度比较快,但运行时性能和内存管理效率不高,通常用于客户端应用程序或者 PC 应用开发和调试。此外,我们知道 JVM 加载字节码后,可以解释执行,也可以编译成本地代码再执行,所以可以配置 JVM 对字节码的处理模式。
3、-Xint:在解释模式(interpreted mode)下运行,-Xint 标记会强制 JVM 解释执行所有的字节码,这当然会降低运行速度,通常低10倍或更多。
4、-Xcomp:-Xcomp 参数与-Xint 正好相反,JVM 在第一次使用时会把所有的字节码编译成本地代码,从而带来最大程度的优化。【注意预热】
5、-Xmixed:-Xmixed 是混合模式,将解释模式和编译模式进行混合使用,有 JVM 自己决定,这是 JVM 的默认模式,也是推荐模式。 我们使用 java -version 可以看到 mixed mode 等信息。
(三)堆内存设置参数
这里包含了堆内存设置、非堆设置、堆外内存设置。
-Xmx, 指定最大堆内存。 如 -Xmx4g。这只是限制了 Heap 部分的最大值为4g。这个内存不包括栈内存,也不包括堆外使用的内存。
-Xms, 指定堆内存空间的初始大小。 如 -Xms4g。 而且指定的内存大小,并不是操作系统实际分配的初始值,而是GC先规划好,用到才分配。 专用服务器上需要保持 –Xms 和 –Xmx 一致,否则应用刚启动可能就有好几个 FullGC。当两者配置不一致时,堆内存扩容可能会导致性能抖动。
-Xmn, 等价于 -XX:NewSize,使用 G1 垃圾收集器 不应该 设置该选项,在其他的某些业务场景下可以设置。官方建议设置为 -Xmx 的 1/2 ~ ¼。
-XX:MaxPermSize=size, 这是 JDK1.7 之前使用的。Java8 默认允许的Meta空间无限大,此参数无效。
-XX:MaxMetaspaceSize=size, Java8 默认不限制 Meta 空间,一般不允许设置该选项。
-XX:MaxDirectMemorySize=size,系统可以使用的最大堆外内存,这个参数跟 -Dsun.nio.MaxDirectMemorySize 效果相同。
-Xss, 设置每个线程栈的字节数,影响栈的深度。 例如 -Xss1m 指定线程栈为1MB,与-XX:ThreadStackSize=1m 等价。
在实际项目运行时,一般设置Xmx时要留出来百分之二三十的余量出来,一般设置为可使用内存的60%到80为最佳,例如一个主机的内存为4G,操作系统和其他进程也会用到一些内存,此时留给JVM虚拟机的内存也就有3.8G左右,这其中还包含了非堆内存(例如各种元数据)和堆外内存(例如直接内存),JVM本身还会消耗掉一些内存,非堆内存、对内内存、JVM自身使用的内存加起来还可能需要300M到500M,因此留给堆内存的大小基本上也就在3.2G左右,这时将Xmx设置为3G是比较合理的。
(四)GC设置参数
这块的参数设置非常多,占据了JVM参数的一大半以上,常规的可以使用 -XX:Use设置使用的垃圾回收器
-XX:+UseG1GC:使用 G1 垃圾回收器
-XX:+UseConcMarkSweepGC:使用 CMS 垃圾回收器
-XX:+UseSerialGC:使用串行垃圾回收器
-XX:+UseParallelGC:使用并行垃圾回收器
在 JDK11 上可以使用ZGC,但是需要解锁实验性的VM开关
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
在 JDK112上可以使用ShenandoahGC,但是需要解锁实验性的VM开关
-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC
(五)分析诊断参数
这个主要是用来做相关的诊断分析的一些参数。
OOM诊断分析:
使用 -XX:+-HeapDumpOnOutOfMemoryError 选项,当 OutOfMemoryError 产生,即内存溢出(堆内存或持久代)时,自动 Dump 堆内存。示例用法: java -XX:+HeapDumpOnOutOfMemoryError -Xmx256m ConsumeHeap
使用 -XX:HeapDumpPath 选项,与 HeapDumpOnOutOfMemoryError 搭配使用,指定内存溢出时 Dump 文件的目录。如果没有指定则默认为启动 Java 程序的工作目录。示例用法: java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/ ConsumeHeap自动 Dump 的 hprof 文件会存储到 /usr/local/ 目录下。
使用 -XX:OnError 选项,发生致命错误时(fatal error)执行的脚本。例如, 写一个脚本来记录出错时间, 执行一些命令,或者 curl 一下某个在线报警的 url。示例用法:java -XX:OnError="gdb - %p" MyApp。可以发现有一个 %p 的格式化字符串,表示进程 PID。
使用 -XX:OnOutOfMemoryError 选项,抛出 OutOfMemoryError 错误时执行的脚本。
使用-XX:ErrorFile=filename 选项,致命错误的日志文件名,绝对路径或者相对路径。
使用 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1506,远程调试。
(六)JavaAgent参数
Agent 是 JVM 中的一项黑科技,其依赖instrament技术,可以通过无侵入方式来做很多事情,比如注入 AOP 代码,执行统计等等,权限非常大。这里简单介绍一下配置选项,详细功能需要专门来讲。
这个黑科技的原理是额外提供一个库,配置在命令行的启动参数里。JVM启动后,在加载所有的类文件之前会先把agent库拉起来,可以用agent内置的一些逻辑对我们加载的所有类文件进行一个预处理,可以对其进行增强或者转换。 所以说这是一个功能非常强大的黑科技,可以在不改动原有jar包或class文件的情况下,在运行期所有的类做一个动态的增强。
设置 agent 的语法如下:
-agentlib:libname[=options] 启用 native 方式的 agent,参考 LD_LIBRARY_PATH 路径。
-agentpath:pathname[=options] 启用 native 方式的 agent。
-javaagent:jarpath[=options] 启用外部的 agent 库,比如 pinpoint.jar 等等。
-Xnoagent 则是禁用所有 agent。
以下示例开启 CPU 使用时间抽样分析:JAVA_OPTS="-agentlib:hprof=cpu=samples,file=cpu.samples.log"
-----------------------------------------------------------
---------------------------------------------
朦胧的夜 留笔~~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?