The java Command

名称

java - 启动Java应用程序

概要

启动一个类文件:

java [选项] 主类 [参数 ...]

启动JAR文件中的主类:

java [选项] -jar JAR文件 [参数 ...]

启动模块中的主类:

java [选项] -m 模块[/主类] [参数 ...]

java [选项] --module 模块[/主类] [参数 ...]

启动单个源文件程序:

java [选项] 源文件 [参数 ...]

选项
可选:指定由空格分隔的命令行选项。查看Java选项概述以获取可用选项的描述。
主类
指定要启动的类的名称。跟在classname后面的命令行条目是主方法的参数。
-jar JAR文件
执行封装在JAR文件中的程序。JAR文件参数是具有包含一行形式为Main-Class:classname的清单的JAR文件的名称,该清单定义了具有public static void main(String[] args)方法的类,该方法作为应用程序的起始点。当使用-jar时,指定的JAR文件是所有用户类的来源,其他类路径设置将被忽略。如果您正在使用JAR文件,请参阅jar
-m--module 模块[/主类]

执行由主类指定的模块中的主类,如果给定,则在模块中指定,如果未给定,则在模块中的值。换句话说,当模块未指定时,可以使用主类,或者在指定时覆盖该值。

查看Java标准选项

源文件
仅用于启动单个源文件程序。指定包含主类的源文件,当使用源文件模式时。查看使用源文件模式启动单个文件源代码程序
参数 ...
可选:跟在主类源文件-jar JAR文件以及-m--module 模块/主类后面的参数将作为参数传递给主类。

描述

java命令启动Java应用程序。它通过启动Java虚拟机(JVM)、加载指定的类并调用该类的main()方法来实现。该方法必须声明为publicstatic,不能返回任何值,并且必须接受String数组作为参数。方法声明的形式如下:

public static void main(String[] args)

在源文件模式下,java命令可以启动在源文件中声明的类。查看使用源文件模式启动单个文件源代码程序以获取有关使用源文件模式的描述。

注意:您可以使用JDK_JAVA_OPTIONS启动器环境变量将其内容前置到java启动器的实际命令行中。查看使用JDK_JAVA_OPTIONS启动器环境变量

默认情况下,不是java命令选项的第一个参数是要调用的类的完全限定名称。如果指定了-jar,则其参数是包含应用程序的类和资源文件的JAR文件的名称。启动类必须在其清单文件中的Main-Class清单头中指示。

在类文件名或JAR文件名之后的参数将传递给main()方法。

javaw

Windows:javaw命令与java相同,只是使用javaw时没有关联的控制台窗口。当您不希望出现命令提示符窗口时,请使用javaw。然而,如果启动失败,javaw启动器将显示一个包含错误信息的对话框。

使用源文件模式启动单个文件源代码程序

要启动在源文件中声明的类,请在源文件模式下运行java启动器。进入源文件模式取决于java命令行上的两个项目:

如果类标识了具有.java扩展名的现有文件,或者指定了--source选项,则选择源文件模式。然后编译并运行源文件。--source选项可用于指定源代码的源版本N。这确定可以使用的API。当设置--source N时,只能使用在JDK N中定义的公共API。

注意:每个版本的N的有效值会随每个版本的发布而更改,添加新值并删除旧值。如果使用不再受支持的N值,您将收到错误消息。支持的N值是当前Java SE版本(21)和有限数量的先前版本,详细信息请参阅javac的命令行帮助,--source--release选项下。

如果文件没有.java扩展名,则必须使用--source选项告诉java命令使用源文件模式。当源文件是要执行的“脚本”时,且源文件的名称不遵循Java源文件的正常命名约定时,将使用--source选项。

在源文件模式下,效果就好像源文件被编译到内存中,并且在源文件中找到的第一个类被执行。原始命令行中源文件名称之后放置的任何参数在执行时将传递给编译后的类。

例如,如果一个文件名为HelloWorld.java,包含一个名为hello.World的类,则启动该类的源文件模式命令将是:

java HelloWorld.java

该示例说明类可以位于命名包中,不需要位于未命名包中。这种使用源文件模式的方式在形式上等同于使用以下两个命令,其中hello.World是包中的类的名称:

javac -d <memory> HelloWorld.java
java -cp <memory> hello.World

在源文件模式下,任何额外的命令行选项处理如下:

在源文件模式下,编译过程如下:

在源文件模式下,执行过程如下:

查看JEP 330:启动单个文件源代码程序获取完整详情。

使用JDK_JAVA_OPTIONS启动器环境变量

JDK_JAVA_OPTIONS将其内容前置到从命令行解析的选项之前。 JDK_JAVA_OPTIONS环境变量的内容是由空格字符(由isspace()确定)分隔的参数列表。 这些参数将前置到传递给java启动器的命令行参数之前。 环境变量的编码要求与系统上的java命令行相同。 JDK_JAVA_OPTIONS环境变量内容的处理方式与命令行中指定的方式相同。

单引号(')或双引号(")可用于包含包含空格字符的参数。 开始引号和第一个匹配的结束引号之间的所有内容都将通过简单地删除引号对来保留。 如果找不到匹配的引号,则启动器将中止并显示错误消息。 支持@文件,因为它们在命令行中指定。 但是,与@文件一样,不支持使用通配符。 为了减轻JDK_JAVA_OPTIONS行为的潜在误用,禁止在环境变量中使用指定主类(例如-jar)或导致java启动器在不执行主类的情况下退出的选项(例如-h)。 如果环境变量中出现任何这些选项,启动器将中止并显示错误消息。 设置JDK_JAVA_OPTIONS时,启动器会向stderr打印一条提醒消息。

示例:

$ export JDK_JAVA_OPTIONS='-g @file1 -Dprop=value @file2 -Dws.prop="white spaces"'
$ java -Xint @file3

等同于以下命令行:

java -g @file1 -Dprop=value @file2 -Dws.prop="white spaces" -Xint @file3

Java选项概述

java命令支持以下类别的广泛选项:

不建议对高级选项进行随意使用。 这些是用于调整Java HotSpot虚拟机操作的特定领域的开发人员选项,通常具有特定的系统要求,并且可能需要对系统配置参数进行特权访问。 在性能调整示例中提供了几个性能调整示例。 这些选项不保证所有JVM实现都支持,并且可能会更改。 高级选项以-XX开头。

布尔选项用于启用默认情况下禁用的功能或禁用默认情况下启用的功能。 这些选项不需要参数。 使用加号(-XX:+OptionName)启用布尔-XX选项,并使用减号(-XX:-OptionName)禁用。

对于需要参数的选项,参数可以通过空格,冒号(:)或等号(=)与选项名称分隔,或者参数可以直接跟随选项(每个选项的确切语法不同)。 如果预期以字节为单位指定大小,则可以不使用后缀,或使用后缀kK表示千字节(KB),mM表示兆字节(MB),或gG表示千兆字节(GB)。 例如,要将大小设置为8 GB,可以指定8g8192m8388608k8589934592作为参数。 如果预期指定百分比,则使用从0到1的数字。 例如,指定0.25表示25%。

以下部分描述了已弃用,过时和已删除的选项:

Java的标准选项

这些是所有JVM实现支持的最常用选项。

注意:要为长选项指定参数,可以使用--name=value--name value

-agentlib:libname[=options]

加载指定的本机代理库。在库名称之后,可以使用逗号分隔的选项列表,这些选项特定于库。如果指定了选项-agentlib:foo,则JVM尝试使用特定于平台的命名约定和位置加载名为foo的库:

  • Linux和其他类POSIX平台: JVM尝试在由LD_LIBRARY_PATH系统变量指定的位置加载名为libfoo.so的库。

  • macOS: JVM尝试在由DYLD_LIBRARY_PATH系统变量指定的位置加载名为libfoo.dylib的库。

  • Windows: JVM尝试在由PATH系统变量指定的位置加载名为foo.dll的库。

    以下示例显示了如何加载Java调试线协议(JDWP)库,并在主类加载之前监听端口8000上的套接字连接,暂停JVM:

    -agentlib:jdwp=transport=dt_socket,server=y,address=8000

-agentpath:pathname[=options]
加载由绝对路径名指定的本机代理库。此选项等效于-agentlib,但使用库的完整路径和文件名。
--class-path classpath, -classpath classpath, 或 -cp classpath

指定要搜索类文件的目录、JAR文件和ZIP存档的列表。

在Windows上,分号(;)分隔此列表中的实体;在其他平台上,是冒号(:)。

指定classpath会覆盖CLASSPATH环境变量的任何设置。如果未使用类路径选项且未设置classpath,则用户类路径包括当前目录(.)。

作为特殊便利,包含星号(*)基本名称的类路径元素被视为等同于指定具有扩展名.jar.JAR的目录中所有文件的列表。Java程序无法区分这两种调用。例如,如果目录mydir包含a.jarb.JAR,则类路径元素mydir/*会扩展为A.jar:b.JAR,只是JAR文件的顺序未指定。指定目录中的所有.jar文件,甚至包括隐藏的文件,在列表中都会包含在内。包含星号(*)的类路径条目会扩展为当前目录中所有jar文件的列表。定义了CLASSPATH环境变量的地方同样会被扩展。任何在启动Java VM之前发生的类路径通配符扩展。Java程序永远不会看到未展开的通配符,除非通过查询环境(例如调用System.getenv("CLASSPATH"))。

--disable-@files
可以在命令行的任何位置使用,包括在参数文件中,以阻止进一步的@filename扩展。此选项在选项之后停止扩展@-argfiles。
--enable-preview
允许类依赖于发布版本的预览功能
--finalization=value
控制JVM是否执行对象的终结。有效值为"enabled"和"disabled"。默认情况下启用终结,因此值"enabled"不起作用。值"disabled"会禁用终结,因此不会调用任何终结器。
--module-path modulepath... 或 -p modulepath

指定应用程序模块的路径元素列表。模块路径的元素可以是指向模块的文件路径或包含模块的目录。每个模块都是模块化JAR或已展开的模块目录。

在Windows上,分号(;)分隔此列表中的路径元素;在其他平台上,是冒号(:)。

--upgrade-module-path modulepath...

指定在运行时映像中查找可升级模块的模块替换的位置元素列表。模块路径的元素可以是指向模块的文件路径或包含模块的目录。每个模块都是模块化JAR或已展开的模块目录。

在Windows上,分号(;)分隔此列表中的路径元素;在其他平台上,是冒号(:)。

--add-modules module[,module...]
指定要解析的根模块,以及初始模块。 module也可以是ALL-DEFAULTALL-SYSTEMALL-MODULE-PATH
--list-modules
列出可观察的模块,然后退出。
-d module_name--describe-module module_name
描述指定的模块,然后退出。
--dry-run
创建VM但不执行主方法。此--dry-run选项可能对验证命令行选项(如模块系统配置)很有用。
--validate-modules
验证所有模块并退出。此选项有助于在模块路径上查找冲突和其他错误。
-Dproperty=value
设置系统属性值。 property变量是一个没有空格的字符串,表示属性的名称。 value变量是表示属性值的字符串。如果value是带有空格的字符串,则用引号括起来(例如-Dfoo="foo bar")。
-disableassertions[:[packagename]...|:classname] 或 -da[:[packagename]...|:classname]

禁用断言。默认情况下,所有包和类中的断言都被禁用。没有参数时,-disableassertions-da)禁用所有包和类中的断言。以...结尾的packagename参数,该开关会禁用指定包及其所有子包中的断言。如果参数只是...,则该开关会禁用当前工作目录中未命名包中的断言。使用classname参数,该开关会禁用指定类中的断言。

-disableassertions-da)选项适用于所有类加载器和系统类(没有类加载器)。有一个例外:如果没有提供参数,则不适用于系统类。这使得在所有类中禁用断言变得容易,除了系统类。-disablesystemassertions选项允许在所有系统类中禁用断言。要显式启用特定包或类中的断言,请使用-enableassertions-ea)选项。这两个选项可以同时使用。例如,要在包com.wombat.fruitbat(及其所有子包)中启用断言,但在类com.wombat.fruitbat.Brickbat中禁用断言运行MyClass应用程序,请使用以下命令:

java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat MyClass

-disablesystemassertions-dsa
在所有系统类中禁用断言。
-enableassertions[:[packagename]...|:classname] 或 -ea[:[packagename]...|:classname]

启用断言。默认情况下,所有包和类中的断言都被禁用。没有参数时,-enableassertions-ea)启用所有包和类中的断言。以...结尾的packagename参数,该开关会启用指定包及其所有子包中的断言。如果参数只是...,则该开关会启用当前工作目录中未命名包中的断言。使用classname参数,该开关会启用指定类中的断言。

-enableassertions-ea)选项适用于所有类加载器和系统类(没有类加载器)。有一个例外:如果没有提供参数,则不适用于系统类。这使得在所有类中启用断言变得容易,除了系统类。-enablesystemassertions选项提供了一个单独的开关,用于在所有系统类中启用断言。要显式禁用特定包或类中的断言,请使用-disableassertions-da)选项。如果单个命令包含这些开关的多个实例,则它们会按顺序处理,然后加载任何类。例如,要在包com.wombat.fruitbat(及其所有子包)中仅启用断言,但在类com.wombat.fruitbat.Brickbat中禁用断言运行MyClass应用程序,请使用以下命令:

java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat MyClass

-enablesystemassertions-esa
在所有系统类中启用断言。
-help, -h, 或 -?
将帮助消息打印到错误流。
--help
将帮助消息打印到输出流。
-javaagent:jarpath[=options]
加载指定的Java编程语言代理。请参阅java.lang.instrument
--show-version
将产品版本打印到输出流并继续。
-showversion
将产品版本打印到错误流并继续。
--show-module-resolution
在启动期间显示模块解析输出。
-splash:imagepath

显示由imagepath指定的启动画面。如果可用,会自动支持和使用HiDPI缩放图像。未缩放的图像文件名,例如image.ext,应始终作为-splash选项的参数传递。会自动选择最合适的缩放图像。

例如,要在启动应用程序时显示images目录中的splash.gif文件,请使用以下选项:

-splash:images/splash.gif

有关更多信息,请参阅SplashScreen API文档。

-verbose:class
显示有关每个加载的类的信息。
-verbose:gc
显示每个垃圾收集(GC)事件的信息。
-verbose:jni
显示有关本地方法和其他Java本机接口(JNI)活动的信息。
-verbose:module
显示正在使用的模块的信息。
--version
将产品版本打印到输出流并退出。
-version
将产品版本打印到错误流并退出。
-X
将额外选项的帮助打印到错误流。
--help-extra
将额外选项的帮助打印到输出流。
@argfile

指定由java命令使用的以@为前缀的一个或多个参数文件。由于类路径中需要的.jar文件,java命令行通常会非常长。@argfile选项通过在shell扩展之后但在参数处理之前使启动器能够展开参数文件的内容,从而克服了命令行长度限制。参数文件中的内容会被展开,否则它们将被指定在命令行上,直到遇到--disable-@files选项为止。

参数文件还可以包含主类名称和所有选项。如果参数文件包含java命令所需的所有选项,则命令行可以简单地是:

java @argfile

有关使用@-argfiles的描述和示例,请参阅java命令行参数文件

Java的额外选项

以下java选项是特定于Java HotSpot虚拟机的通用选项。

显示所有设置,然后继续。
-XshowSettings:category

显示设置并继续。此选项的可能类别参数包括以下内容:

all
显示所有设置类别。这是默认值。
locale
显示与区域设置相关的设置。
properties
显示与系统属性相关的设置。
vm
显示JVM的设置。
system
仅适用于Linux: 显示主机系统或容器配置并继续。
-Xss size

设置线程堆栈大小(以字节为单位)。附加字母kK表示KB,mM表示MB,gG表示GB。根据操作系统的要求,实际大小可能会四舍五入为系统页面大小的倍数。默认值取决于平台。例如:

  • Linux/x64:1024 KB

  • Linux/Aarch64:2048 KB

  • macOS/x64:1024 KB

  • macOS/Aarch64:2048 KB

  • Windows:默认值取决于虚拟内存

以下示例将线程堆栈大小设置为不同单位的1024 KB:

-Xss1m
-Xss1024k
-Xss1048576

此选项类似于-XX:ThreadStackSize

--add-reads module=target-module(,target-module)*
更新module以读取target-module,无论模块声明如何。 target-module可以是所有未命名模块以读取所有未命名模块。
--add-exports module/package=target-module(,target-module)*
更新module以将package导出到target-module,无论模块声明如何。 target-module可以是所有未命名模块以导出到所有未命名模块。
--add-opens module/package=target-module(,target-module)*
更新module以向target-module开放package,无论模块声明如何。
--limit-modules module[,module...]
指定可观察模块的宇宙限制。
--patch-module module=file(;file)*
使用JAR文件或目录中的类和资源覆盖或增强模块。
--source version
设置源文件模式中的源版本。

macOS的额外选项

以下额外选项是macOS特定的。

-XstartOnFirstThread
在第一个(AppKit)线程上运行main()方法。
-Xdock:name=应用程序名称
覆盖在dock中显示的默认应用程序名称。
-Xdock:icon=图标文件路径
覆盖在dock中显示的默认图标。

Java的高级选项

这些java选项可用于启用其他高级选项。

-XX:+UnlockDiagnosticVMOptions

解锁用于诊断JVM的选项。默认情况下,此选项已禁用,诊断选项不可用。

通过使用此选项启用的命令行选项不受支持。如果在使用这些选项时遇到问题,则很可能需要在Oracle支持人员协助调查之前,无需使用任何这些不受支持的选项来重现问题。还有可能删除任何这些选项或更改其行为而不发出任何警告。

-XX:+UnlockExperimentalVMOptions
解锁在JVM中提供实验性功能的选项。默认情况下,此选项已禁用,实验性功能不可用。

Java的高级运行时选项

这些java选项控制Java HotSpot VM的运行时行为。

-XX:ActiveProcessorCount=x

覆盖虚拟机将用于计算线程池大小的CPU数量,用于各种操作,如垃圾回收和ForkJoinPool。

虚拟机通常从操作系统确定可用处理器的数量。当在docker容器中运行多个Java进程时,此标志可用于分区CPU资源。即使未启用UseContainerSupport,此标志也会受到尊重。有关启用和禁用容器支持的描述,请参见-XX:-UseContainerSupport

-XX:AllocateHeapAt=path

接受文件系统路径,并使用内存映射在内存设备上分配对象堆。使用此选项使HotSpot VM能够在用户指定的替代内存设备上分配Java对象堆,例如NV-DIMM。

可以使用具有与DRAM相同语义的替代内存设备,包括原子操作的语义,而无需更改现有应用程序代码,用于对象堆而不更改现有应用程序代码。所有其他内存结构(如代码堆,元空间和线程堆栈)继续驻留在DRAM中。

一些操作系统通过文件系统公开非DRAM内存。在这些文件系统中,内存映射文件绕过页面缓存,并提供虚拟内存到设备上的物理内存的直接映射。现有的堆相关标志(如-Xmx-Xms)以及垃圾回收相关标志继续像以前一样工作。

-XX:-CompactStrings

禁用紧凑字符串功能。默认情况下,此选项已启用。启用此选项时,仅包含单字节字符的Java字符串将以ISO-8859-1 / Latin-1编码的单字节每字符字符串的形式内部表示和存储。这将减少仅包含单字节字符的字符串所需的空间量50%。对于至少包含一个多字节字符的Java字符串:这些将以UTF-16编码的每字符2字节的形式表示和存储。禁用紧凑字符串功能将强制使用UTF-16编码作为所有Java字符串的内部表示。

禁用紧凑字符串可能有益的情况包括以下情况:

  • 当已知应用程序主要将分配多字节字符字符串时

  • 在从Java SE 8迁移到Java SE 9时观察到性能回归的意外事件中,并且分析显示紧凑字符串引入了回归

在这两种情况下,禁用紧凑字符串是有意义的。

-XX:ErrorFile=filename

指定发生不可恢复错误时写入错误数据的路径和文件名。默认情况下,此文件在当前工作目录中创建,并命名为hs_err_pidpid.log,其中pid是遇到错误的进程的标识符。

以下示例显示如何设置默认日志文件(请注意,进程的标识符指定为%p):

-XX:ErrorFile=./hs_err_pid%p.log

  • 非Windows:以下示例显示如何将错误日志设置为/var/log/java/java_error.log

    -XX:ErrorFile=/var/log/java/java_error.log

  • Windows:以下示例显示如何将错误日志文件设置为C:/log/java/java_error.log

    -XX:ErrorFile=C:/log/java/java_error.log

如果文件存在且可写,则将覆盖该文件。否则,如果由于空间不足,权限问题或其他问题而无法在指定目录中创建文件,则该文件将在操作系统的临时目录中创建:

  • 非Windows:临时目录为/tmp

  • Windows:临时目录由TMP环境变量的值指定;如果未定义该环境变量,则使用TEMP环境变量的值。

-XX:+ExtensiveErrorReports
启用在ErrorFile中报告更详尽的错误信息。此选项可在需要最大信息的环境中打开 - 即使生成的日志可能非常大和/或包含可能被视为敏感的信息。信息可能因版本而异,跨不同平台而异。默认情况下,此选项已禁用。
-XX:FlightRecorderOptions=parameter=value (或) -XX:FlightRecorderOptions:parameter=value

设置控制JFR行为的参数。可以通过用逗号分隔它们来指定多个参数。

以下列表包含可用的JFR parameter=value条目:

globalbuffersize=size
指定用于数据保留的主内存总量。默认值基于为memorysize指定的值。更改memorysize参数以更改全局缓冲区的大小。
maxchunksize=size
指定录制中数据块的最大大小(以字节为单位)。附加mM以指定以兆字节(MB)的大小,或gG以指定以千兆字节(GB)的大小。默认情况下,数据块的最大大小设置为12 MB。允许的最小值为1 MB。
memorysize=size
确定应使用多少缓冲器内存,并根据指定的大小设置globalbuffersizenumglobalbuffers参数。附加mM以指定以兆字节(MB)的大小,或gG以指定以千兆字节(GB)的大小。默认情况下,内存大小设置为10 MB。
numglobalbuffers
指定使用的全局缓冲区的数量。默认值基于指定的内存大小。更改memorysize参数以更改全局缓冲区的数量。
old-object-queue-size=number-of-objects
要跟踪的旧对象的最大数量。默认情况下,对象的数量设置为256。
preserve-repository={true|false}
指定在JVM退出后是否应保留存储在磁盘存储库中的文件。如果为false,则文件将被删除。默认情况下,此参数已禁用。
repository=path
指定用于临时磁盘存储的存储库(目录)。默认情况下,使用系统的临时目录。
retransform={true|false}
指定是否应使用JVMTI重新转换事件类。如果为false,则在加载事件类时添加插装。默认情况下,此参数已启用。
stackdepth=depth
堆栈跟踪的堆栈深度。默认情况下,深度设置为64个方法调用。最大值为2048。大于64的值可能会带来显着开销并降低性能。
threadbuffersize=size
指定每个线程本地缓冲区大小(以字节为单位)。默认情况下,本地缓冲区大小设置为8千字节,最小值为4千字节。覆盖此参数可能会降低性能,不建议这样做。
-XX:LargePageSizeInBytes=size

设置JVM使用的最大大页大小(以字节为单位)。size参数必须是环境支持的有效页面大小才能生效。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认情况下,大小设置为0,这意味着JVM将使用环境的默认大页大小作为大页的最大大小。请参见大页

以下示例描述如何将大页大小设置为1千兆字节(GB):

-XX:LargePageSizeInBytes=1g

-XX:MaxDirectMemorySize=size

设置java.nio包直接缓冲区分配的最大总大小(以字节为单位)。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。如果未设置,该标志将被忽略,并且JVM将自动选择NIO直接缓冲区分配的大小。

以下示例说明如何以不同单位将NIO大小设置为1024 KB:

-XX:MaxDirectMemorySize=1m
-XX:MaxDirectMemorySize=1024k
-XX:MaxDirectMemorySize=1048576
-XX:-MaxFDLimit
禁用将打开文件描述符的软限制设置为硬限制的尝试。默认情况下,此选项在所有平台上启用,但在Windows上被忽略。您可能需要在macOS上禁用此选项的唯一情况是,其使用会导致最大限制为10240,低于实际系统最大限制。
-XX:NativeMemoryTracking=mode

指定用于跟踪JVM本机内存使用情况的模式。此选项的可能mode参数包括以下内容:

off
指示不跟踪JVM本机内存使用情况。如果未指定-XX:NativeMemoryTracking选项,则这是默认行为。
summary
仅跟踪JVM子系统(如Java堆,类,代码和线程)的内存使用情况。
detail
除了跟踪JVM子系统的内存使用情况外,还跟踪每个CallSite,每个虚拟内存区域及其已提交区域的内存使用情况。
-XX:+NeverActAsServerClassMachine

启用“客户端VM仿真”模式,仅使用C1 JIT编译器,32Mb CodeCache和Serial GC。JVM可以使用的最大内存量(由-XX:MaxRAM=n标志控制)默认设置为1GB。字符串“emulated-client”将添加到JVM版本字符串中。

默认情况下,该标志仅在32位Windows上设置为true,在所有其他情况下设置为false

如果命令行上使用了以下任何标志,则不会启用“客户端VM仿真”模式:

-XX:{+|-}TieredCompilation
-XX:CompilationMode=mode
-XX:TieredStopAtLevel=n
-XX:{+|-}EnableJVMCI
-XX:{+|-}UseJVMCICompiler
-XX:ObjectAlignmentInBytes=alignment

设置Java对象的内存对齐(以字节为单位)。默认情况下,该值设置为8字节。指定的值应为2的幂,并且必须在8和256(包括)范围内。此选项使得在大型Java堆大小下可以使用压缩指针。

以字节为单位计算的堆大小限制为:

4GB * ObjectAlignmentInBytes

注意:随着对齐值的增加,对象之间未使用的空间也会增加。因此,在大型Java堆大小下使用压缩指针可能不会带来任何好处。

-XX:OnError=string

设置在发生不可恢复错误时运行的自定义命令或一系列以分号分隔的命令。如果字符串包含空格,则必须用引号括起来。

  • 非Windows系统:以下示例显示了如何使用-XX:OnError选项运行gcore命令创建核心映像,并启动gdb调试器以在发生不可恢复错误时附加到进程(%p代表当前进程标识符):

    -XX:OnError="gcore %p;gdb -p %p"

  • Windows系统:以下示例显示了如何使用-XX:OnError选项运行userdump.exe实用程序以在发生不可恢复错误时获取崩溃转储(%p代表当前进程标识符)。此示例假定userdump.exe实用程序的路径已在PATH环境变量中指定:

    -XX:OnError="userdump.exe %p"

-XX:OnOutOfMemoryError=string
设置在首次抛出OutOfMemoryError异常时运行的自定义命令或一系列以分号分隔的命令。如果字符串包含空格,则必须用引号括起来。有关命令字符串示例,请参阅-XX:OnError选项的描述。
-XX:+PrintCommandLineFlags
启用打印在命令行中出现的经过人体工程学选择的JVM标志。了解JVM设置的人体工程学值(如堆空间大小和所选垃圾收集器)可能很有用。默认情况下,此选项已禁用,不会打印标志。
-XX:+PreserveFramePointer
选择使用RBP寄存器作为通用寄存器(-XX:-PreserveFramePointer)和使用RBP寄存器来保存当前执行方法的帧指针(-XX:+PreserveFramePointer)。如果帧指针可用,则外部分析工具(例如Linux perf)可以构建更准确的堆栈跟踪。
-XX:+PrintNMTStatistics
启用在启用本机内存跟踪时在JVM退出时打印收集的本机内存跟踪数据(请参阅-XX:NativeMemoryTracking)。默认情况下,此选项已禁用,不会打印本机内存跟踪数据。
-XX:SharedArchiveFile=path

指定类数据共享(CDS)存档文件的路径和名称

请参阅应用程序类数据共享

-XX:SharedArchiveConfigFile=shared_config_file
指定要添加到存档文件的附加共享数据。
-XX:SharedClassListFile=file_name

指定包含要存储在类数据共享(CDS)存档中的类名称的文本文件。此文件每行包含一个类的完整名称,斜杠(/)替换点(.)。例如,要指定类java.lang.Objecthello.Main,创建一个包含以下两行的文本文件:

java/lang/Object
hello/Main

在此文本文件中指定的类应包括应用程序常用的类。它们可以包括应用程序、扩展或引导类路径中的任何类。

请参阅应用程序类数据共享

-XX:+ShowCodeDetailsInExceptionMessages
启用改进的NullPointerException消息打印。当应用程序抛出NullPointerException时,此选项使JVM能够分析程序的字节码指令,以确定确切哪个引用为null,并使用空详细消息描述源。空详细消息由NullPointerException.getMessage()计算并返回,并将作为异常消息与方法、文件名和行号一起打印。默认情况下,此选项已启用。
-XX:+ShowMessageBoxOnError
启用在JVM遇到不可恢复错误时显示对话框。这可以防止JVM退出并保持进程活动,以便您可以附加调试器以调查错误的原因。默认情况下,此选项已禁用。
-XX:StartFlightRecording=parameter=value

为Java应用程序启动JFR记录。此选项相当于在运行时启动记录的JFR.start诊断命令。在启动JFR记录时,您可以设置以下parameter=value条目:

delay=time
指定Java应用程序启动时间和记录开始之间的延迟。附加s以指定以秒为单位的时间,m表示分钟,h表示小时,或d表示天(例如,指定10m表示10分钟)。默认情况下,没有延迟,此参数设置为0。
disk={true|false}
指定在记录时是否将数据写入磁盘。默认情况下,此参数已启用。
dumponexit={true|false}
指定在JVM关闭时是否转储正在运行的记录。如果启用且未输入filename,则记录将写入启动进程所在目录中的文件。文件名是一个包含进程ID、记录ID和当前时间戳的系统生成名称,类似于hotspot-pid-47496-id-1-2018_01_25_19_10_41.jfr。默认情况下,此参数已禁用。
duration=time
指定记录的持续时间。附加s以指定以秒为单位的时间,m表示分钟,h表示小时,或d表示天(例如,指定5h表示5小时)。默认情况下,持续时间不受限制,此参数设置为0。
filename=path

指定在停止记录时写入记录的文件的路径和名称,例如:

  • recording.jfr
  • /home/user/recordings/recording.jfr
  • c:\recordings\recording.jfr

如果文件名中指定了%p和/或%t,则会扩展为JVM的PID和当前时间戳。

name=identifier
获取记录的名称和标识符。
maxage=time
指定保留记录的磁盘数据的最大年龄。此参数仅在disk参数设置为true时有效。附加s以指定以秒为单位的时间,m表示分钟,h表示小时,或d表示天(例如,指定30s表示30秒)。默认情况下,最大年龄不受限制,此参数设置为0s
maxsize=size
指定保留记录的磁盘数据的最大大小(以字节为单位)。此参数仅在disk参数设置为true时有效。该值不能小于使用-XX:FlightRecorderOptions设置的maxchunksize参数的值。附加mM以指定以兆字节为单位的大小,或gG以指定以千兆字节为单位的大小。默认情况下,磁盘数据的最大大小不受限制,此参数设置为0
path-to-gc-roots={true|false}

指定是否在记录结束时收集垃圾收集(GC)根的路径。默认情况下,此参数已禁用。

GC根的路径对于查找内存泄漏很有用,但收集它是耗时的。仅在启动对您怀疑存在内存泄漏的应用程序的记录时启用此选项。如果settings参数设置为profile,则包括从分配潜在泄漏对象的位置的堆栈跟踪在内的信息被收集。

settings=path

指定事件设置文件(类型为JFC)的路径和名称。默认情况下,使用位于JAVA_HOME/lib/jfr中的default.jfc文件,该文件收集一组预定义的信息,对性能影响很小,可与持续运行的记录一起使用。

还提供了第二个设置文件profile.jfc,它提供比默认配置更多的数据,但可能有更多的开销并影响性能。当需要更多信息时,可以在短时间内使用此配置。

option=value
指定要修改的选项值。要列出可用选项,请使用JAVA_HOME/bin/jfr工具。
event-setting=value
指定要修改的事件设置值。使用形式:<event-name>#<setting-name>=<value>。要添加新的事件设置,请使用'+'前缀事件名称。

-XX:ThreadStackSize=size

设置Java线程堆栈大小(以千字节为单位)。使用缩放后缀,例如k,将导致千字节值的缩放,以便-XX:ThreadStackSize=1k将Java线程堆栈大小设置为1024*1024字节或1兆字节。默认值取决于平台。例如:

  • Linux/x64:1024 KB

  • Linux/Aarch64:2048 KB

  • macOS/x64:1024 KB

  • macOS/Aarch64:2048 KB

  • Windows:默认值取决于虚拟内存

以下示例显示如何以不同单位将线程堆栈大小设置为1兆字节:

-XX:ThreadStackSize=1k
-XX:ThreadStackSize=1024

此选项类似于-Xss

-XX:-UseCompressedOops

禁用压缩指针的使用。默认情况下,此选项已启用,并且使用压缩指针。这将自动将经济确定的Java堆大小限制为可以由压缩指针覆盖的最大内存量。默认情况下,此范围为32 GB。

启用压缩 oops 后,对象引用将以32位偏移量表示,而不是64位指针,这通常会提高在Java堆大小小于压缩 oops 指针范围时运行应用程序的性能。此选项仅适用于64位JVM。

可以在Java堆大小大于32 GB时使用压缩指针。请参阅-XX:ObjectAlignmentInBytes选项。

-XX:-UseContainerSupport

仅适用于Linux: VM现在提供自动容器检测支持,允许VM确定在docker容器中运行的Java进程可用的内存量和处理器数量。它使用此信息来分配系统资源。此标志的默认值为true,默认情况下启用容器支持。可以使用-XX:-UseContainerSupport来禁用它。

统一日志可用于帮助诊断与此支持相关的问题。

使用-Xlog:os+container=trace以最大程度记录容器信息。有关使用统一日志的说明,请参阅使用JVM统一日志框架启用日志记录

-XX:+UseHugeTLBFS

仅适用于Linux: 此选项相当于指定-XX:+UseLargePages。默认情况下,此选项已禁用。此选项在内存保留时预先分配所有大页面,因此JVM无法动态增长或缩小大页面内存区域;如果您希望实现此行为,请参阅-XX:UseTransparentHugePages

请参阅大页面

-XX:+UseLargePages

启用大页面内存的使用。默认情况下,此选项已禁用,不使用大页面内存。

请参阅大页面

-XX:+UseTransparentHugePages
仅适用于Linux: 启用可以动态增长或缩小的大页面的使用。默认情况下,此选项已禁用。您可能会遇到透明巨大页面的性能问题,因为操作系统会移动其他页面以创建巨大页面;此选项可供实验使用。
-XX:+AllowUserSignalHandlers
非Windows: 启用应用程序安装信号处理程序。默认情况下,此选项已禁用,不允许应用程序安装信号处理程序。
-XX:VMOptionsFile=文件名
允许用户在文件中指定VM选项,例如,java -XX:VMOptionsFile=/var/my_vm_options HelloWorld
-XX:UseBranchProtection=模式

仅适用于Linux AArch64: 指定分支保护模式。除none之外的所有选项都要求VM已启用分支保护。此外,为了获得完整保护,应用程序提供的任何本机库都应使用相同级别的保护进行编译。

此选项的可能模式参数包括以下内容:

none
不使用分支保护。这是默认值。
standard
启用当前平台上可用的所有分支保护模式。
pac-ret
启用对基于ROP的攻击的保护。(仅限AArch64 8.3+)

Java高级JIT编译器选项

这些java选项控制Java HotSpot VM执行的动态即时(JIT)编译。

-XX:AllocateInstancePrefetchLines=lines

设置实例分配指针之前预取的行数。默认情况下,预取的行数设置为1:

-XX:AllocateInstancePrefetchLines=1

-XX:AllocatePrefetchDistance=size

设置对象分配的预取距离(以字节为单位)。即将写入新对象值的内存将从上一个分配对象的地址开始预取到这个距离。每个Java线程都有自己的分配点。

负值表示基于平台选择预取距离。正值表示要预取的字节数。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认值设置为-1。

以下示例显示如何将预取距离设置为1024字节:

-XX:AllocatePrefetchDistance=1024

-XX:AllocatePrefetchInstr=instruction

设置在分配指针之前预取的预取指令。可能的值为0到3。实际值取决于平台的指令。默认情况下,预取指令设置为0:

-XX:AllocatePrefetchInstr=0

-XX:AllocatePrefetchLines=lines

通过使用在编译代码中生成的预取指令,设置在最后一个对象分配后加载的缓存行数。如果最后分配的对象是实例,则默认值为1,如果是数组,则为3。

以下示例显示如何将加载的缓存行数设置为5:

-XX:AllocatePrefetchLines=5

-XX:AllocatePrefetchStepSize=size

设置顺序预取指令的步长(以字节为单位)。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认情况下,步长设置为16字节:

-XX:AllocatePrefetchStepSize=16

-XX:AllocatePrefetchStyle=style

为预取指令设置生成的代码样式。 style 参数是从0到3的整数:

0
不生成预取指令。
1
在每次分配后执行预取指令。这是默认设置。
2
使用线程本地分配块(TLAB)水印指针来确定何时执行预取指令。
3
每个缓存行生成一个预取指令。
-XX:+BackgroundCompilation
启用后台编译。此选项默认启用。要禁用后台编译,请指定-XX:-BackgroundCompilation(这相当于指定-Xbatch)。
-XX:CICompilerCount=threads

设置用于编译的编译器线程数。默认情况下,编译器线程的数量根据可用于编译代码的CPU和内存数量自动选择。以下示例显示如何将线程数设置为2:

-XX:CICompilerCount=2

-XX:+UseDynamicNumberOfCompilerThreads
动态创建编译器线程,直到达到-XX:CICompilerCount指定的限制。此选项默认启用。
-XX:CompileCommand=command,method[,option]

指定在method上执行的command。例如,要排除String类的indexOf()方法不被编译,使用以下命令:

-XX:CompileCommand=exclude,java/lang/String.indexOf

请注意,包括所有包和子包,用斜杠(/)分隔的完整类名。为了更容易地剪切和粘贴操作,还可以使用-XX:+PrintCompilation-XX:+LogCompilation选项生成的方法名格式:

-XX:CompileCommand=exclude,java.lang.String::indexOf

如果方法未带有签名,则该命令将应用于所有具有指定名称的方法。但是,您还可以在类文件格式中指定方法的签名。在这种情况下,应将参数括在引号中,因为否则shell将分号视为命令结束。例如,如果要排除仅String类的indexOf(String)方法不被编译,请使用以下命令:

-XX:CompileCommand="exclude,java/lang/String.indexOf,(Ljava/lang/String;)I"

您还可以使用星号(*)作为类和方法名称的通配符。例如,要排除所有类中的所有indexOf()方法不被编译,请使用以下命令:

-XX:CompileCommand=exclude,*.indexOf

逗号和句点是空格的别名,使得通过shell传递编译器命令更容易。您可以使用空格作为分隔符将参数传递给-XX:CompileCommand,方法是将参数括在引号中:

-XX:CompileCommand="exclude java/lang/String indexOf"

请注意,在使用-XX:CompileCommand选项解析通过命令行传递的命令后,JIT编译器会从.hotspot_compiler文件中读取命令。您可以向此文件添加命令,或使用-XX:CompileCommandFile选项指定不同的文件。

要添加多个命令,可以多次指定-XX:CompileCommand选项,或使用换行符(\n)分隔每个参数。以下命令可用:

break
在调试JVM时设置断点,以在指定方法的编译开始时停止。
compileonly
排除所有方法的编译,除了指定的方法。作为替代,您可以使用-XX:CompileOnly选项,该选项允许您指定多个方法。
dontinline
阻止指定方法的内联。
exclude
排除指定方法的编译。
help
打印-XX:CompileCommand选项的帮助消息。
inline
尝试内联指定方法。
log
排除编译日志记录(使用-XX:+LogCompilation选项)对所有方法的编译,除了指定的方法。默认情况下,所有编译方法都会记录日志。
option

将JIT编译选项传递给指定方法,替换最后一个参数(option)。编译选项在方法名之后设置。例如,要为StringBuffer类的append()方法启用BlockLayoutByFrequency选项,请使用以下命令:

-XX:CompileCommand=option,java/lang/StringBuffer.append,BlockLayoutByFrequency

您可以指定多个编译选项,用逗号或空格分隔。

print
编译指定方法后打印生成的汇编代码。
quiet

指示不打印编译命令。默认情况下,您使用-XX:CompileCommand选项指定的命令会被打印;例如,如果排除String类的indexOf()方法的编译,则以下内容会打印到标准输出:

CompilerOracle: exclude java/lang/String.indexOf

您可以通过在其他-XX:CompileCommand选项之前指定-XX:CompileCommand=quiet选项来抑制此输出。

-XX:CompileCommandFile=filename

设置从中读取JIT编译器命令的文件。默认情况下,使用.hotspot_compiler文件存储JIT编译器执行的命令。

命令文件中的每一行表示一个命令,一个类名和一个用于该命令的方法名。例如,此行将打印String类的toString()方法的汇编代码:

print java/lang/String toString

如果您正在使用JIT编译器执行方法的命令,请参阅-XX:CompileCommand选项。

-XX:CompilerDirectivesFile=file

在程序启动时将文件中的指令添加到指令堆栈。请参阅编译器控制

-XX:CompilerDirectivesFile选项必须与解锁诊断JVM选项的-XX:UnlockDiagnosticVMOptions选项一起使用。

-XX:+CompilerDirectivesPrint

在程序启动时或添加新指令时打印指令堆栈。

-XX:+CompilerDirectivesPrint选项必须与解锁诊断JVM选项的-XX:UnlockDiagnosticVMOptions选项一起使用。

-XX:CompileOnly=methods

设置应限制编译的方法列表(用逗号分隔)。只有指定的方法会被编译。使用完整的类名(包括包和子包)指定每个方法。例如,要仅编译String类的length()方法和List类的size()方法,请使用以下设置:

-XX:CompileOnly=java/lang/String.length,java/util/List.size

注意,需要指定完整的类名,包括所有用斜杠(/)分隔的包和子包。为了更容易地剪切和粘贴操作,也可以使用-XX:+PrintCompilation-XX:+LogCompilation选项生成的方法名格式:

-XX:CompileOnly=java.lang.String::length,java.util.List::size

虽然不支持通配符,但可以指定仅类或包名以编译该类或包中的所有方法,也可以指定仅方法以编译任何类中具有此名称的方法:

-XX:CompileOnly=java/lang/String
-XX:CompileOnly=java/lang
-XX:CompileOnly=.length
-XX:CompileThresholdScaling=scale
统一控制首次编译。此选项控制在分层和非分层操作模式下何时首次编译方法。CompileThresholdScaling选项的值为0到+Inf之间的浮点数,用于调整对应于当前操作模式(分层和非分层)的阈值。将CompileThresholdScaling设置为小于1.0的值会导致较早的编译,而大于1.0的值会延迟编译。将CompileThresholdScaling设置为0等效于禁用编译。
-XX:+DoEscapeAnalysis
启用逃逸分析的使用。此选项默认启用。要禁用逃逸分析的使用,请指定-XX:-DoEscapeAnalysis
-XX:InitialCodeCacheSize=size

设置初始代码缓存大小(以字节为单位)。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认值取决于平台。初始代码缓存大小不应小于系统的最小内存页大小。以下示例显示如何将初始代码缓存大小设置为32 KB:

-XX:InitialCodeCacheSize=32k

-XX:+Inline
启用方法内联。此选项默认启用以提高性能。要禁用方法内联,请指定-XX:-Inline
-XX:InlineSmallCode=size

设置已编译方法可能被内联的最大代码大小(以字节为单位)。此标志仅适用于C2编译器。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认值取决于平台和分层编译是否启用。在以下示例中,它设置为1000字节:

-XX:InlineSmallCode=1000

-XX:+LogCompilation

启用将编译活动记录到名为hotspot.log的文件中。您可以使用-XX:LogFile选项指定不同的日志文件路径和名称。

默认情况下,此选项已禁用,不会记录编译活动。必须与解锁诊断JVM选项的-XX:UnlockDiagnosticVMOptions选项一起使用-XX:+LogCompilation选项。

您可以通过使用-XX:+PrintCompilation选项在每次编译方法时在控制台打印消息来启用详细的诊断输出。

-XX:FreqInlineSize=size

设置要内联的热方法的最大字节码大小(以字节为单位)。此标志仅适用于C2编译器。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认值取决于平台。在以下示例中,它设置为325字节:

-XX:FreqInlineSize=325

-XX:MaxInlineSize=size

设置要内联的冷方法的最大字节码大小(以字节为单位)。此标志仅适用于C2编译器。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认情况下,最大字节码大小设置为35字节:

-XX:MaxInlineSize=35

-XX:C1MaxInlineSize=size

设置要内联的冷方法的最大字节码大小(以字节为单位)。此标志仅适用于C1编译器。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认情况下,最大字节码大小设置为35字节:

-XX:MaxInlineSize=35

-XX:MaxTrivialSize=size

设置要内联的微不足道方法的最大字节码大小(以字节为单位)。此标志仅适用于C2编译器。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认情况下,微不足道方法的最大字节码大小设置为6字节:

-XX:MaxTrivialSize=6

-XX:C1MaxTrivialSize=size

设置要内联的微不足道方法的最大字节码大小(以字节为单位)。此标志仅适用于C1编译器。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认情况下,微不足道方法的最大字节码大小设置为6字节:

-XX:MaxTrivialSize=6

-XX:MaxNodeLimit=nodes

设置在单个方法编译期间要使用的最大节点数。默认情况下,该值取决于启用的功能。在以下示例中,最大节点数设置为100,000:

-XX:MaxNodeLimit=100000

-XX:NonNMethodCodeHeapSize=size

设置包含非方法代码的代码段的大小(以字节为单位)。

包含非方法代码的非方法代码段,例如编译器缓冲区和字节码解释器。此代码类型永远保留在代码缓存中。仅当启用-XX:SegmentedCodeCache时才使用此标志。

-XX:NonProfiledCodeHeapSize=size
设置包含非概要方法的代码段的大小(以字节为单位)。仅当启用-XX:SegmentedCodeCache时使用此标志。
-XX:+OptimizeStringConcat
启用String连接操作的优化。此选项默认启用。要禁用String连接操作的优化,请指定-XX:-OptimizeStringConcat
-XX:+PrintAssembly

通过使用外部hsdis-<arch>.so.dll库启用对字节码和本地方法的汇编代码的打印。对于Windows上的64位VM,它是hsdis-amd64.dll。这使您可以查看生成的代码,有助于诊断性能问题。

默认情况下,此选项已禁用,不会打印汇编代码。必须与解锁诊断JVM选项的-XX:UnlockDiagnosticVMOptions选项一起使用-XX:+PrintAssembly选项。

-XX:ProfiledCodeHeapSize=size
设置包含概要方法的代码段的大小(以字节为单位)。仅当启用-XX:SegmentedCodeCache时使用此标志。
-XX:+PrintCompilation

通过在每次编译方法时在控制台打印消息来启用JVM的详细诊断输出。这使您可以查看实际编译的方法。默认情况下,此选项已禁用,不会打印诊断输出。

您还可以通过使用-XX:+LogCompilation选项将编译活动记录到文件中。

-XX:+PrintInlining

启用内联决策的打印。这让您可以看到哪些方法正在被内联。

默认情况下,此选项已禁用,不会打印内联信息。必须与解锁诊断JVM选项的-XX:+UnlockDiagnosticVMOptions选项一起使用-XX:+PrintInlining选项。

-XX:ReservedCodeCacheSize=size
设置用于JIT编译代码的最大代码缓存大小(以字节为单位)。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认最大代码缓存大小为240 MB;如果使用-XX:-TieredCompilation选项禁用分层编译,则默认大小为48 MB。此选项限制为2 GB;否则会生成错误。最大代码缓存大小不应小于初始代码缓存大小;请参阅选项-XX:InitialCodeCacheSize
-XX:RTMAbortRatio=abort_ratio
指定RTM中止比率,表示为所有执行的RTM事务的百分比(%)。如果中止事务的数量大于此比率,则编译代码将被取消优化。当启用-XX:+UseRTMDeopt选项时使用此比率。此选项的默认值为50。这意味着如果所有事务的50%被中止,则编译代码将被取消优化。
-XX:RTMRetryCount=number_of_retries
指定在RTM锁定代码中中止或繁忙时重试的次数。此选项的默认值为5。必须启用-XX:UseRTMLocking选项。
-XX:+SegmentedCodeCache

启用代码缓存的分段,否则代码缓存将由一个大段组成。使用-XX:+SegmentedCodeCache,将为非方法代码、已分析方法代码和未分析方法代码使用单独的段。这些段在运行时不会调整大小。优点是更好地控制内存占用、减少代码碎片化,并由于改善局部性而改善CPU iTLB(指令转换查找缓冲器)和指令缓存行为。

如果启用分层编译(-XX:+TieredCompilation)并且保留的代码缓存大小(-XX:ReservedCodeCacheSize)至少为240 MB,则默认情况下启用此功能。

-XX:StartAggressiveSweepingAt=百分比
强制对活动方法进行堆栈扫描,以便在代码缓存仅剩下给定百分比空闲时积极删除未使用的代码。默认值为10%。
-XX:-TieredCompilation
禁用分层编译的使用。默认情况下,此选项已启用。
-XX:UseSSE=版本
启用指定版本的SSE指令集的使用。默认情况下设置为可用的最高支持版本(仅限x86)。
-XX:UseAVX=版本
启用指定版本的AVX指令集的使用。默认情况下设置为可用的最高支持版本(仅限x86)。
-XX:+UseAES
启用支持硬件的AES内部函数,前提是硬件支持。在具有必要指令的硬件上,默认情况下启用此选项。-XX:+UseAESUseAESIntrinsics一起使用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseAESIntrinsics

启用AES内部函数。指定-XX:+UseAESIntrinsics等同于启用-XX:+UseAES。要禁用基于硬件的AES内部函数,请指定-XX:-UseAES -XX:-UseAESIntrinsics。例如,要启用硬件AES,请使用以下标志:

-XX:+UseAES -XX:+UseAESIntrinsics

现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions

-XX:+UseAESCTRIntrinsics
类似于-XX:+UseAESIntrinsics,启用AES/CTR内部函数。
-XX:+UseGHASHIntrinsics
控制GHASH内部函数的使用。在支持相应指令的平台上默认启用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseChaCha20Intrinsics
启用ChaCha20内部函数。在支持的平台上默认启用。要禁用ChaCha20内部函数,请指定-XX:-UseChaCha20Intrinsics。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UsePoly1305Intrinsics
启用Poly1305内部函数。在支持的平台上默认启用。要禁用Poly1305内部函数,请指定-XX:-UsePoly1305Intrinsics。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseBASE64Intrinsics
控制java.util.Base64的加速BASE64编码例程的使用。在支持的平台上默认启用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseAdler32Intrinsics
控制java.util.zip.Adler32的Adler32校验算法内部函数的使用。在支持的平台上默认启用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseCRC32Intrinsics
控制java.util.zip.CRC32的CRC32内部函数的使用。在支持的平台上默认启用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseCRC32CIntrinsics
控制java.util.zip.CRC32C的CRC32C内部函数的使用。在支持的平台上默认启用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseSHA

启用一些硬件支持的SHA密码哈希函数的内部函数。UseSHA选项与UseSHA1IntrinsicsUseSHA256IntrinsicsUseSHA512Intrinsics选项一起使用。

UseSHAUseSHA*Intrinsics标志在支持相应指令的机器上默认启用。

此功能仅在使用sun.security.provider.Sun提供程序进行SHA操作时适用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions

要禁用所有基于硬件的SHA内部函数,请指定-XX:-UseSHA。要仅禁用特定的SHA内部函数,请使用相应的选项。例如:-XX:-UseSHA256Intrinsics

-XX:+UseSHA1Intrinsics
启用SHA-1密码哈希函数的内部函数。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseSHA256Intrinsics
启用SHA-224和SHA-256密码哈希函数的内部函数。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseSHA512Intrinsics
启用SHA-384和SHA-512密码哈希函数的内部函数。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseMathExactIntrinsics
启用各种java.lang.Math.*Exact()函数的内部函数。默认启用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseMultiplyToLenIntrinsic
启用BigInteger.multiplyToLen()的内部函数。在支持的平台上默认启用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseSquareToLenIntrinsic
启用BigInteger.squareToLen()的内部函数。在支持的平台上默认启用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseMulAddIntrinsic
启用BigInteger.mulAdd()的内部函数。在支持的平台上默认启用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseMontgomeryMultiplyIntrinsic
启用BigInteger.montgomeryMultiply()的内部函数。在支持的平台上默认启用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseMontgomerySquareIntrinsic
启用BigInteger.montgomerySquare()的内部函数。在支持的平台上默认启用。现在控制内部函数的标志需要选项-XX:+UnlockDiagnosticVMOptions
-XX:+UseCMoveUnconditionally
无论盈利性分析如何,生成CMove(标量和矢量)指令。
-XX:+UseCodeCacheFlushing
在关闭编译器之前刷新代码缓存。默认情况下启用此选项。要在关闭编译器之前禁用代码缓存刷新,请指定-XX:-UseCodeCacheFlushing
-XX:+UseCondCardMark
在更新卡表之前检查卡是否已标记。默认情况下禁用此选项。仅应在具有多个插槽的机器上使用,其中它提高了依赖并发操作的Java应用程序的性能。
-XX:+UseCountedLoopSafepoints
在计数循环中保留安全点。其默认值取决于所选垃圾收集器是否需要低延迟安全点。
-XX:LoopStripMiningIter=迭代次数
控制内部条带挖掘循环中的迭代次数。条带挖掘将计数循环转换为两级嵌套循环。安全点保留在外部循环中,而内部循环可以以全速执行。此选项控制内部循环中的最大迭代次数。默认值为1,000。
-XX:LoopStripMiningIterShortLoop=迭代次数
控制循环条带挖掘优化。迭代次数少于指定值的循环将不包含安全点。默认值为-XX:LoopStripMiningIter的1/10。
-XX:+UseFMA
启用硬件支持的FMA内部函数,适用于支持FMA指令的硬件(例如Intel和ARM64)。为java.lang.Math.fma(a, b, c)方法生成FMA内部函数,用于计算( a * b + c )表达式的值。
-XX:+UseRTMDeopt
根据中止比率自动调整RTM锁定。中止比率由-XX:RTMAbortRatio选项指定。如果中止事务的数量超过中止比率,则包含锁的方法将被取消优化,并重新编译为所有锁为普通锁的方法。默认情况下禁用此选项。必须启用-XX:+UseRTMLocking选项。
-XX:+UseRTMLocking

为所有膨胀的锁生成受限事务内存(RTM)锁定代码,正常的锁定机制作为回退处理程序。此选项默认情况下处于禁用状态。与RTM相关的选项仅适用于支持事务同步扩展(TSX)的x86 CPU。

RTM是Intel的TSX的一部分,它是x86指令集扩展,有助于创建多线程应用程序。RTM引入了新指令XBEGINXABORTXENDXTESTXBEGINXEND指令将一组指令封装为事务运行。如果在运行事务时未发现冲突,则在XEND指令时一起提交内存和寄存器修改。XABORT指令可用于显式中止事务,XTEST指令检查一组指令是否在事务中运行。

当另一个线程尝试访问相同事务时,事务上的锁被膨胀,从而阻塞原始未请求访问事务的线程。RTM要求在事务中止或失败时指定一组回退操作。RTM锁是已委托给TSX系统的锁。

RTM提高了高度争用的锁在关键区域(不得同时被多个线程访问的代码)中的性能,低冲突。RTM还提高了粗粒度锁定的性能,在多线程应用程序中通常表现不佳。(粗粒度锁定是长时间持有锁以最小化获取和释放锁的开销的策略,而细粒度锁定是尽可能在必要时才锁定并尽快解锁以实现最大并行性的策略。)此外,对于被不同线程使用的轻度争用锁,RTM可以减少虚假缓存行共享,也称为缓存行乒乓。当来自不同处理器的多个线程正在访问不同资源,但这些资源共享相同的缓存行时,就会发生这种情况。结果是,处理器反复使其他处理器的缓存行无效,这迫使它们从主存中读取而不是从它们的缓存中读取。

-XX:+UseSuperWord
启用将标量操作转换为超字操作的优化。超字是一种矢量化优化。此选项默认情况下处于启用状态。要禁用将标量操作转换为超字操作,请指定-XX:-UseSuperWord

Java高级服务性选项

这些java选项提供了收集系统信息和执行广泛调试的能力。

-XX:+DisableAttachMechanism

禁用允许工具附加到JVM的机制。默认情况下,此选项已禁用,这意味着附加机制已启用,您可以使用诊断和故障排除工具,如jcmdjstackjmapjinfo

注意: JDK附带的诸如jcmdjinfojmapjstack等工具,在使用来自一个JDK版本的工具来排查不同JDK版本时不受支持。

-XX:+DTraceAllocProbes
Linux和macOS: 启用dtrace工具探测对象分配。
-XX:+DTraceMethodProbes
Linux和macOS: 启用dtrace工具探测方法进入和退出。
-XX:+DTraceMonitorProbes
Linux和macOS: 启用dtrace工具探测监视器事件。
-XX:+HeapDumpOnOutOfMemoryError
启用在抛出java.lang.OutOfMemoryError异常时使用堆分析器(HPROF)将Java堆转储到当前目录中的文件。您可以使用-XX:HeapDumpPath选项显式设置堆转储文件路径和名称。默认情况下,此选项已禁用,当抛出OutOfMemoryError异常时不会转储堆。
-XX:HeapDumpPath=路径

设置在设置-XX:+HeapDumpOnOutOfMemoryError选项时由堆分析器(HPROF)提供的堆转储的路径和文件名。默认情况下,文件将在当前工作目录中创建,并命名为java_pid<pid>.hprof,其中<pid>是导致错误的进程标识符。以下示例显示如何显式设置默认文件(%p代表当前进程标识符):

-XX:HeapDumpPath=./java_pid%p.hprof

  • 非Windows: 以下示例显示如何将堆转储文件设置为/var/log/java/java_heapdump.hprof

    -XX:HeapDumpPath=/var/log/java/java_heapdump.hprof

  • Windows: 以下示例显示如何将堆转储文件设置为C:/log/java/java_heapdump.log

    -XX:HeapDumpPath=C:/log/java/java_heapdump.log

-XX:LogFile=路径

设置日志数据写入的路径和文件名。默认情况下,文件将在当前工作目录中创建,并命名为hotspot.log

  • 非Windows: 以下示例显示如何将日志文件设置为/var/log/java/hotspot.log

    -XX:LogFile=/var/log/java/hotspot.log

  • Windows: 以下示例显示如何将日志文件设置为C:/log/java/hotspot.log

    -XX:LogFile=C:/log/java/hotspot.log

-XX:+PrintClassHistogram

在以下事件之后启用打印类实例直方图:

  • 非Windows: Control+\SIGQUIT

  • Windows: Control+CSIGTERM

默认情况下,此选项已禁用。

设置此选项等同于运行jmap -histo命令,或者jcmd pid GC.class_histogram命令,其中pid是当前Java进程标识符。

-XX:+PrintConcurrentLocks

在以下事件之后启用打印java.util.concurrent锁:

  • 非Windows: Control+\SIGQUIT

  • Windows: Control+CSIGTERM

默认情况下,此选项已禁用。

设置此选项等同于运行jstack -l命令或者jcmd pid Thread.print -l命令,其中pid是当前Java进程标识符。

-XX:+PrintFlagsRanges
打印指定的范围并允许值的自动测试。请参阅验证Java虚拟机标志参数
-XX:+PerfDataSaveToFile

如果启用,当Java应用程序退出时保存jstat二进制数据。此二进制数据保存在名为hsperfdata_pid的文件中,其中pid是您运行的Java应用程序的进程标识符。使用jstat命令显示此文件中包含的性能数据,如下所示:

jstat -class file:///路径/hsperfdata_pid

jstat -gc file:///路径/hsperfdata_pid

-XX:+UsePerfData
启用perfdata功能。默认情况下启用此选项以允许JVM监视和性能测试。禁用它会抑制hsperfdata_userid目录的创建。要禁用perfdata功能,请指定-XX:-UsePerfData

Java高级垃圾回收选项

这些java选项控制Java HotSpot VM执行垃圾回收(GC)的方式。

-XX:+AggressiveHeap
启用Java堆优化。根据计算机的配置(RAM和CPU),将各种参数设置为适合长时间运行且具有密集内存分配的作业的最佳状态。默认情况下,此选项被禁用,并且堆大小配置不那么激进。
-XX:+AlwaysPreTouch
请求VM在从操作系统请求Java堆后并在将内存分配给应用程序之前触摸Java堆上的每个页面。默认情况下,此选项被禁用,并且所有页面在应用程序使用堆空间时都被提交。
-XX:ConcGCThreads=threads

设置用于并发GC的线程数。将threads设置为大约并行垃圾收集线程数量的1/4。默认值取决于JVM可用的CPU数量。

例如,要将并发GC的线程数设置为2,请指定以下选项:

-XX:ConcGCThreads=2

-XX:+DisableExplicitGC
启用禁用对System.gc()方法调用的处理的选项。默认情况下,此选项被禁用,意味着对System.gc()的调用会被处理。如果禁用对System.gc()的调用处理,则JVM仍会在必要时执行GC。
-XX:+ExplicitGCInvokesConcurrent
启用通过System.gc()请求调用并发GC的选项。默认情况下,此选项被禁用,只能与-XX:+UseG1GC选项一起启用。
-XX:G1AdaptiveIHOPNumInitialSamples=number
当启用-XX:UseAdaptiveIHOP时,此选项设置用于收集样本的完成标记周期数,直到G1自适应确定-XX:InitiatingHeapOccupancyPercent的最佳值。在此之前,G1直接使用-XX:InitiatingHeapOccupancyPercent的值来实现此目的。默认值为3。
-XX:G1HeapRegionSize=size

设置在使用垃圾优先(G1)收集器时将Java堆划分为的区域大小。该值是2的幂,范围从1 MB到32 MB。默认区域大小是根据堆大小的人体工程学目标约为2048个区域确定的。

以下示例将分区大小设置为16 MB:

-XX:G1HeapRegionSize=16m

-XX:G1HeapWastePercent=percent
设置愿意浪费的堆百分比。当可回收百分比小于堆浪费百分比时,Java HotSpot VM不会启动混合垃圾收集周期。默认值为5%。
-XX:G1MaxNewSizePercent=percent

设置用作年轻代大小最大值的堆大小百分比。默认值为Java堆的60%。

这是一个实验性标志。此设置替换了-XX:DefaultMaxNewGenPercent设置。

-XX:G1MixedGCCountTarget=number
设置在标记周期后收集具有最多G1MixedGCLIveThresholdPercent活数据的旧区域的混合垃圾收集目标数量。默认值为8个混合垃圾收集。混合收集的目标是保持在此目标数量内。
-XX:G1MixedGCLiveThresholdPercent=percent

设置要包括在混合垃圾收集周期中的旧区域的占用阈值。默认占用率为85%。

这是一个实验性标志。此设置替换了-XX:G1OldCSetRegionLiveThresholdPercent设置。

-XX:G1NewSizePercent=percent

设置用作年轻代大小最小值的堆百分比。默认值为Java堆的5%。

这是一个实验性标志。此设置替换了-XX:DefaultMinNewGenPercent设置。

-XX:G1OldCSetRegionThresholdPercent=percent
设置在混合垃圾收集周期中要收集的旧区域数量的上限。默认值为Java堆的10%。
-XX:G1ReservePercent=percent

设置作为虚假上限保留的堆百分比(0到50),以减少G1收集器的晋升失败可能性。增加或减少百分比时,请确保按同等比例调整总Java堆。默认情况下,此选项设置为10%。

以下示例将保留堆设置为20%:

-XX:G1ReservePercent=20

-XX:+G1UseAdaptiveIHOP

控制自适应计算老年代占用率以开始准备进行老年代收集的后台工作。如果启用,G1在最初几次使用时使用-XX:InitiatingHeapOccupancyPercent,由-XX:G1AdaptiveIHOPNumInitialSamples的值指定,并在此之后自适应计算新的启动占用率的最佳值。否则,老年代收集过程始终从由-XX:InitiatingHeapOccupancyPercent确定的老年代占用率开始。

默认情况下启用。

-XX:InitialHeapSize=size

设置内存分配池的初始大小(以字节为单位)。此值必须为0或1024的倍数,大于1 MB。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认值根据系统配置在运行时选择。

以下示例显示如何使用各种单位将分配内存的大小设置为6 MB:

-XX:InitialHeapSize=6291456
-XX:InitialHeapSize=6144k
-XX:InitialHeapSize=6m

如果将此选项设置为0,则初始大小将设置为为老年代和年轻代分配的大小之和。年轻代堆的大小可以使用-XX:NewSize选项设置。请注意,-Xms选项设置堆的最小和初始大小。如果-Xms在命令行上出现在-XX:InitialHeapSize之后,则初始堆大小将设置为-Xms指定的值。

-XX:InitialRAMPercentage=percent

将JVM在应用人体工程学启发式之前使用的Java堆的初始内存量设置为作为-XX:MaxRAM选项描述的最大量的百分比。默认值为1.5625%。

以下示例显示如何设置用于Java堆的初始内存量的百分比:

-XX:InitialRAMPercentage=5

-XX:InitialSurvivorRatio=ratio

设置吞吐量垃圾收集器(通过-XX:+UseParallelGC选项启用)使用的初始幸存者空间比率。默认情况下,通过使用-XX:+UseParallelGC选项启用吞吐量垃圾收集器时启用自适应调整,并根据应用程序行为调整幸存者空间大小,从初始值开始。如果禁用自适应调整(使用-XX:-UseAdaptiveSizePolicy选项),则应使用-XX:SurvivorRatio选项设置整个应用程序执行期间幸存者空间的大小。

可以使用以下公式计算基于年轻代大小(Y)和初始幸存者空间比率(R)的幸存者空间的初始大小(S):

S=Y/(R+2)

方程中的2表示两个幸存者空间。指定的初始幸存者空间比率值越大,初始幸存者空间大小就越小。

默认情况下,初始幸存者空间比率设置为8。如果使用默认值为2 MB的年轻代空间大小,则初始幸存者空间大小为0.2 MB。

以下示例显示如何将初始幸存者空间比率设置为4:

-XX:InitialSurvivorRatio=4

-XX:InitiatingHeapOccupancyPercent=percent

设置开始G1垃圾收集器的前几个并发标记周期的老年代占用率(0到100)。

默认情况下,初始值设置为45%。值为0表示从一开始就不停地进行并发GC周期,直到G1自适应设置此值。

另请参阅-XX:G1UseAdaptiveIHOP-XX:G1AdaptiveIHOPNumInitialSamples选项。

以下示例显示如何将初始堆占用率设置为75%:

-XX:InitiatingHeapOccupancyPercent=75

-XX:MaxGCPauseMillis=time

设置最大GC暂停时间的目标(以毫秒为单位)。这是一个软目标,JVM将尽最大努力实现。指定的值不会根据堆大小进行调整。默认情况下,对于G1,最大暂停时间目标为200毫秒。其他分代收集器默认情况下不使用暂停时间目标。

以下示例显示如何将最大目标暂停时间设置为500毫秒:

-XX:MaxGCPauseMillis=500

-XX:MaxHeapSize=size

设置内存分配池的最大大小(以字节为单位)。此值必须为1024的倍数,大于2 MB。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认值根据系统配置在运行时选择。对于服务器部署,通常将-XX:InitialHeapSize-XX:MaxHeapSize选项设置为相同的值。

以下示例显示如何使用各种单位将分配内存的最大允许大小设置为80 MB:

-XX:MaxHeapSize=83886080
-XX:MaxHeapSize=81920k
-XX:MaxHeapSize=80m

-XX:MaxHeapSize选项等同于-Xmx

-XX:MaxHeapFreeRatio=percent

设置GC事件后允许的最大空闲堆空间百分比(0到100)。如果空闲堆空间扩展到此值以上,则堆将被收缩。默认情况下,此值设置为70%。

通过降低命令行选项-XX:MaxHeapFreeRatio(默认值为70%)和-XX:MinHeapFreeRatio(默认值为40%)的参数值来最小化Java堆大小。将MaxHeapFreeRatio降低至至少10%,将MinHeapFreeRatio降低至5%已成功减小堆大小而不会有太大性能回退;但是,结果可能会因应用程序而异。尝试不同的值,直到它们尽可能低但仍保持可接受的性能。

-XX:MaxHeapFreeRatio=10 -XX:MinHeapFreeRatio=5

试图保持堆较小的客户还应添加选项-XX:-ShrinkHeapInSteps。有关使用此选项通过减少嵌入式应用程序的动态占用空间来保持Java堆较小的描述,请参阅性能调整示例

-XX:MaxMetaspaceSize=大小

设置可为类元数据分配的本机内存的最大量。默认情况下,大小不受限制。应用程序的元数据量取决于应用程序本身、其他正在运行的应用程序以及系统上可用的内存量。

以下示例显示如何将最大类元数据大小设置为256 MB:

-XX:MaxMetaspaceSize=256m

-XX:MaxNewSize=大小
设置年轻代(幼儿园)堆的最大大小(以字节为单位)。默认值是根据人体工程学设置的。
-XX:MaxRAM=大小

在应用人体工程学启发式方法之前,设置JVM在应用Java堆之前可以使用的最大内存量。默认值是JVM进程可用内存的最大量或128 GB中较低的一个。

JVM进程可用内存的最大量是机器的物理内存和环境设置的任何约束(例如容器)的最小值。

指定此选项会禁用自动使用压缩oops,如果此选项和其他影响内存最大量的选项的组合结果大于压缩oops可寻址的内存范围。有关压缩oops的更多信息,请参阅-XX:UseCompressedOops

以下示例显示如何将用于调整Java堆大小的可用内存的最大量设置为2 GB:

-XX:MaxRAM=2G

-XX:MaxRAMPercentage=百分比

在应用描述的-XX:MaxRAM选项中确定的最大量的百分比作为Java堆使用之前,设置JVM在应用人体工程学启发式方法之前可以使用的最大内存量。默认值为25%。

指定此选项会禁用自动使用压缩oops,如果此选项和其他影响内存最大量的选项的组合结果大于压缩oops可寻址的内存范围。有关压缩oops的更多信息,请参阅-XX:UseCompressedOops

以下示例显示如何设置用于Java堆的最大内存量的百分比:

-XX:MaxRAMPercentage=75

-XX:MinRAMPercentage=百分比

在小堆中,设置JVM在应用描述的-XX:MaxRAM选项中确定的最大量的百分比作为Java堆使用之前,设置JVM在应用人体工程学启发式方法之前可以使用的最大内存量。小堆是大约125 MB的堆。默认值为50%。

以下示例显示如何设置小堆的Java堆使用的最大内存量的百分比:

-XX:MinRAMPercentage=75

-XX:MaxTenuringThreshold=阈值

设置用于自适应GC大小的最大tenuring阈值。最大值为15。对于并行(吞吐量)收集器,默认值为15。

以下示例显示如何将最大tenuring阈值设置为10:

-XX:MaxTenuringThreshold=10

-XX:MetaspaceSize=大小
设置分配的类元数据空间的大小,第一次超过此大小时触发垃圾回收。此垃圾回收的阈值会根据使用的元数据量增加或减少。默认大小取决于平台。
-XX:MinHeapFreeRatio=百分比

设置GC事件后允许的最小空闲堆空间百分比(0到100)。如果空闲堆空间低于此值,则堆将被扩展。默认情况下,此值设置为40%。

通过降低命令行选项-XX:MaxHeapFreeRatio(默认值为70%)和-XX:MinHeapFreeRatio(默认值为40%)的参数值来最小化Java堆大小。将MaxHeapFreeRatio降低至至少10%,将MinHeapFreeRatio降低至5%已成功减小堆大小而不会有太大性能回退;但是,结果可能会因应用程序而异。尝试不同的值,直到它们尽可能低但仍保持可接受的性能。

-XX:MaxHeapFreeRatio=10 -XX:MinHeapFreeRatio=5

试图保持堆较小的客户还应添加选项-XX:-ShrinkHeapInSteps。有关使用此选项通过减少嵌入式应用程序的动态占用空间来保持Java堆较小的描述,请参阅性能调整示例

-XX:MinHeapSize=大小

设置内存分配池的最小大小(以字节为单位)。此值必须为0或1024的倍数,大于1 MB。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。默认值根据系统配置在运行时选择。

以下示例显示如何使用不同单位将分配内存的最小大小设置为6 MB:

-XX:MinHeapSize=6291456
-XX:MinHeapSize=6144k
-XX:MinHeapSize=6m

如果将此选项设置为0,则最小大小将设置为与初始大小相同的值。

-XX:NewRatio=比率

设置年轻代和老年代大小之间的比率。默认情况下,此选项设置为2。以下示例显示如何将年轻代到老年代的比率设置为1:

-XX:NewRatio=1

-XX:NewSize=大小

设置年轻代(幼儿园)堆的初始大小(以字节为单位)。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。

堆的年轻代区域用于新对象。在此区域中执行GC的频率比其他区域更高。如果年轻代的大小过低,则会执行大量的小GC。如果大小过高,则只会执行完整GC,这可能需要很长时间才能完成。建议将年轻代的大小保持在整体堆大小的25%至50%之间。

以下示例显示如何使用不同单位将年轻代的初始大小设置为256 MB:

-XX:NewSize=256m
-XX:NewSize=262144k
-XX:NewSize=268435456

-XX:NewSize选项等同于-Xmn

-XX:ParallelGCThreads=线程

设置停止-世界(STW)工作线程的数量。默认值取决于JVM可用的CPU数量和所选的垃圾收集器。

例如,要将G1 GC的线程数设置为2,请指定以下选项:

-XX:ParallelGCThreads=2

-XX:+ParallelRefProcEnabled
启用并行引用处理。默认情况下,此选项已禁用。
-XX:+PrintAdaptiveSizePolicy
启用自适应生成大小信息的打印。默认情况下,此选项已禁用。
-XX:+ScavengeBeforeFullGC
启用每次完整GC之前对年轻代进行GC。此选项默认启用。建议不要禁用它,因为在每次完整GC之前对年轻代进行清理可以减少从老年代空间中可达对象到年轻代空间中的对象数量。要禁用每次完整GC之前对年轻代进行GC,请指定选项-XX:-ScavengeBeforeFullGC
-XX:SoftRefLRUPolicyMSPerMB=时间

设置软引用对象在最后一次引用后在堆上保持活动的时间(以毫秒为单位)。默认值是堆中每个自由兆字节的一秒寿命。 -XX:SoftRefLRUPolicyMSPerMB选项接受表示每个当前堆大小的兆字节(对于Java HotSpot Client VM)或最大可能堆大小(对于Java HotSpot Server VM)的毫秒的整数值。这种差异意味着Client VM倾向于刷新软引用而不是增加堆大小,而Server VM倾向于增加堆大小而不是刷新软引用。在后一种情况下,-Xmx选项的值对软引用的垃圾收集速度有显著影响。

以下示例显示如何将值设置为2.5秒:

-XX:SoftRefLRUPolicyMSPerMB=2500

-XX:-ShrinkHeapInSteps

逐步将Java堆减小到由选项-XX:MaxHeapFreeRatio指定的目标大小。此选项默认启用。如果禁用,则会立即将Java堆减小到目标大小,而不需要多个垃圾回收周期。如果要最小化Java堆大小,请禁用此选项。当禁用此选项时,可能会遇到性能下降。

有关使用MaxHeapFreeRatio选项通过减少嵌入式应用程序的动态占用空间来保持Java堆较小的描述,请参阅性能调整示例

-XX:StringDeduplicationAgeThreshold=阈值

标识达到指定年龄的String对象,被视为重复消除的候选对象。对象的年龄是它经历垃圾回收的次数的度量。有时这被称为终身。

注意:在达到此年龄之前被提升到旧堆区的String对象总是被视为重复消除的候选对象。此选项的默认值为3。请参阅-XX:+UseStringDeduplication选项。

-XX:SurvivorRatio=比率

设置伊甸空间大小和幸存者空间大小之间的比率。默认情况下,此选项设置为8。以下示例显示如何将伊甸/幸存者空间比率设置为4:

-XX:SurvivorRatio=4

-XX:TargetSurvivorRatio=百分比

设置年轻垃圾回收后使用的幸存者空间的期望百分比(0到100)。默认情况下,此选项设置为50%。

以下示例显示如何将目标幸存者空间比率设置为30%:

-XX:TargetSurvivorRatio=30

-XX:TLABSize=大小

设置线程本地分配缓冲区(TLAB)的初始大小(以字节为单位)。附加字母kK表示千字节,mM表示兆字节,gG表示千兆字节。如果将此选项设置为0,则JVM会自动选择初始大小。

以下示例显示如何将初始TLAB大小设置为512 KB:

-XX:TLABSize=512k

-XX:+UseAdaptiveSizePolicy
启用自适应生成大小的使用。此选项默认启用。要禁用自适应生成大小,请指定-XX:-UseAdaptiveSizePolicy并显式设置内存分配池的大小。请参阅-XX:SurvivorRatio选项。
-XX:+UseG1GC
启用垃圾优先(G1)垃圾收集器的使用。这是一种面向多处理器机器且具有大量RAM的服务器风格垃圾收集器。此选项以高概率实现GC暂停时间目标,同时保持良好的吞吐量。G1收集器推荐用于需要大堆(大小约为6 GB或更大)且具有有限GC延迟要求(稳定且可预测的暂停时间低于0.5秒)的应用程序。默认情况下,此选项已启用,并且G1被用作默认垃圾收集器。
-XX:+UseGCOverheadLimit
启用一项策略,限制JVM在GC上花费的时间比例,直到抛出OutOfMemoryError异常。此选项默认启用,且并行GC将在花费在垃圾回收上的总时间超过98%且恢复的堆空间不到2%时抛出OutOfMemoryError。当堆较小时,此功能可用于防止应用程序长时间运行而几乎没有进展。要禁用此选项,请指定选项-XX:-UseGCOverheadLimit
-XX:+UseNUMA
启用在具有非统一内存架构(NUMA)的机器上优化应用程序性能,通过增加应用程序对延迟较低内存的使用。默认情况下,此选项已禁用,不会对NUMA进行任何优化。此选项仅在使用并行垃圾收集器时可用(-XX:+UseParallelGC)。
-XX:+UseParallelGC

启用并行清扫垃圾收集器(也称为吞吐量收集器)的使用,通过利用多个处理器提高应用程序的性能。

默认情况下,此选项已禁用,并使用默认收集器。

-XX:+UseSerialGC
启用串行垃圾收集器的使用。这通常是小型和简单应用程序的最佳选择,不需要从垃圾收集中获得任何特殊功能。默认情况下,此选项已禁用,并使用默认收集器。
-XX:+UseSHM

仅适用于Linux:启用JVM使用共享内存设置大页。

请参阅大页以设置大页。

-XX:+UseStringDeduplication

启用字符串重复消除。默认情况下,此选项已禁用。要使用此选项,必须启用垃圾优先(G1)垃圾收集器。

字符串重复消除通过利用许多相同的String对象来减少Java堆上String对象的内存占用。相同的String对象可以指向并共享相同的字符数组,而不是每个String对象都指向自己的字符数组。

-XX:+UseTLAB
启用年轻代空间中的线程本地分配块(TLAB)的使用。此选项默认启用。要禁用TLAB的使用,请指定选项-XX:-UseTLAB
-XX:+UseZGC
启用Z垃圾收集器(ZGC)的使用。这是一种低延迟垃圾收集器,提供几毫秒的最大暂停时间,但会带来一些吞吐量成本。暂停时间与使用的堆大小无关。支持堆大小从8MB到16TB。
-XX:ZAllocationSpikeTolerance=因子
设置ZGC的分配尖峰容忍度。默认情况下,此选项设置为2.0。此因子描述了预期的分配尖峰水平。例如,使用3.0的因子意味着当前分配速率可能随时增加三倍。
-XX:ZCollectionInterval=
设置使用ZGC时两次GC周期之间的最大间隔(以秒为单位)。默认情况下,此选项设置为0(禁用)。
-XX:ZFragmentationLimit=百分比
设置ZGC的最大可接受堆碎片化(以百分比表示)。默认情况下,此选项设置为25。使用较低的值将导致堆更积极地进行压缩,以在更多CPU时间的代价下回收更多内存。
-XX:+ZProactive
启用使用ZGC时主动GC周期。默认情况下,此选项已启用。如果预计进行主动GC周期对正在运行的应用程序影响很小,则ZGC将启动主动GC周期。如果应用程序大部分时间处于空闲状态或几乎不分配对象,但仍希望保持堆大小并允许引用处理即使堆上有大量空闲空间时发生,这将很有用。
-XX:+ZUncommit
启用使用ZGC时未使用堆内存的取消分配。默认情况下,此选项已启用。取消分配未使用的堆内存将降低JVM的内存占用,并使该内存可供其他进程使用。
-XX:ZUncommitDelay=
设置堆内存在未使用多久后才能取消分配的时间量(以秒为单位)。默认情况下,此选项设置为300(5分钟)。提交和取消分配内存是相对昂贵的操作。使用较低的值将导致堆内存更早取消分配,但可能很快需要重新提交。

已弃用的Java选项

这些java选项已被弃用,可能会在未来的JDK版本中被移除。它们仍然被接受并执行,但在使用它们时会发出警告。

-Xfuture
启用严格的类文件格式检查,强制执行对类文件格式规范的严格一致性。开发人员在开发新代码时应使用此标志。未来的版本中,更严格的检查可能会成为默认设置。
-Xloggc:文件名

设置应将详细的GC事件信息重定向到的文件以进行日志记录。如果在同一java命令中同时给出-Xloggc-verbose:gc,则-Xloggc选项会覆盖-Xlog:gc:文件名。请参阅使用JVM统一日志记录框架启用日志记录。

示例:

-Xlog:gc:garbage-collection.log

-XX:+FlightRecorder
在应用程序运行时启用Java Flight Recorder(JFR)。自JDK 8u40以来,不再需要此选项来使用JFR。
-XX:InitialRAMFraction=比率

将JVM在将作为-XX:MaxRAM选项描述的最大量的内存之前可以用于Java堆的初始内存量设置为最大量的比率。默认值为64。

请改用选项-XX:InitialRAMPercentage

-XX:MaxRAMFraction=比率

将JVM在将作为-XX:MaxRAM选项描述的最大量的内存之前可以用于Java堆的最大量设置为最大量的比率。默认值为4。

指定此选项会禁用自动使用压缩指针(compressed oops),如果此选项和其他影响最大内存量的选项的组合的结果大于压缩指针可寻址的内存范围。有关压缩指针的更多信息,请参阅-XX:UseCompressedOops

请改用选项-XX:MaxRAMPercentage

-XX:MinRAMFraction=比率

将JVM在将作为-XX:MaxRAM选项描述的最大量的内存之前可以用于Java堆的最大量设置为最大量的比率,用于小堆。小堆是大约125 MB的堆。默认值为2。

请改用选项-XX:MinRAMPercentage

已废弃的Java选项

这些java选项仍然被接受,但会被忽略,并在使用它们时发出警告。

--illegal-access=参数
受控的放宽强封装,如在JEP 261中定义。此选项在JDK 16中已被弃用,并在JDK 17中被JEP 403废弃。

已移除的Java选项

这些java选项已在JDK 21中移除,使用它们会导致错误:

Unrecognized VM option 选项名称

-XX:+ExtendedDTraceProbes
Linux和macOS: 启用影响性能的额外dtrace工具探测。默认情况下,此选项已禁用,dtrace仅执行标准探测。请改用以下标志的组合:-XX:+DTraceMethodProbes-XX:+DTraceAllocProbes-XX:+DTraceMonitorProbes

有关以前版本中已移除选项的列表和描述,请参阅以下文档中的已移除的Java选项部分:

java命令行参数文件

您可以通过使用@参数文件来缩短或简化java命令,以指定一个或多个包含参数(如选项和类名)的文本文件,这些参数将传递给java命令。这样可以在任何操作系统上创建任意长度的java命令。

在命令行中,使用@符号(@)前缀来标识包含java选项和类名的参数文件。当java命令遇到以@符号(@)开头的文件时,它会将该文件的内容展开为参数列表,就像它们在命令行上指定的那样。

java启动器会展开参数文件的内容,直到遇到--disable-@files选项。您可以在命令行的任何位置使用--disable-@files选项,包括在参数文件中,以停止@参数文件的展开。

以下内容描述了java参数文件的语法:

参数文件中开放或部分引号的示例

在参数文件中,

-cp "lib/
cool/
app/
jars

这被解释为:

-cp lib/cool/app/jars

参数文件中反斜杠字符用另一个反斜杠字符转义的示例

-cp c:\Program Files (x86)\Java\jre\lib\ext;c:\Program Files\Java\jre9\lib\ext

必须在参数文件中指定反斜杠字符为:

-cp "c:\\Program Files (x86)\\Java\\jre\\lib\\ext;c:\\Program Files\\Java\\jre9\\lib\\ext"

参数文件中使用EOL转义强制连接行的示例

-cp "/lib/cool app/jars:\
    /lib/another app/jars"

这被解释为:

-cp /lib/cool app/jars:/lib/another app/jars

参数文件中带有前导空格的行继续示例

-cp "/lib/cool\
\app/jars"

这被解释为:

-cp /lib/cool app/jars

使用单个参数文件的示例

您可以使用单个参数文件,例如在以下示例中的myargumentfile,来保存所有必需的java参数:

java @myargumentfile

使用带路径的参数文件的示例

您可以在参数文件中包含相对路径;但是,它们是相对于当前工作目录而不是参数文件本身的路径。在以下示例中,path1/optionspath2/options代表具有不同路径的参数文件。它们包含的任何相对路径都是相对于当前工作目录而不是参数文件:

java @path1/options @path2/classes

代码堆状态分析

概述

有时候了解JVM代码堆的当前状态将有助于回答诸如以下问题:

  • JIT为什么一次又一次地关闭然后重新启用?

  • 代码堆空间都去哪了?

  • 为什么方法清理器的效果不佳?

为了提供这种洞察力,实现了一个代码堆状态分析功能,它使得能够实时分析代码堆。分析过程分为两部分。第一部分检查整个代码堆并汇总所有被认为有用或重要的信息。第二部分由几个独立步骤组成,打印收集的信息,重点放在数据的不同方面。数据收集和打印是基于“按请求”进行的。

语法

可以使用以下命令发出实时、即时分析的请求:

jcmd pid Compiler.CodeHeap_Analytics [function] [granularity]

如果您只对运行示例工作负载后代码堆的外观感兴趣,可以使用命令行选项:

-Xlog:codecache=Trace

要查看代码堆状态,当存在“CodeCache full”条件时,使用以下命令行选项启动VM:

-Xlog:codecache=Debug

请参阅代码堆状态分析(OpenJDK),详细描述了代码堆状态分析功能、支持的功能和粒度选项。

使用JVM统一日志框架启用日志记录

您可以使用-Xlog选项配置或启用Java虚拟机(JVM)统一日志框架的日志记录。

概要

-Xlog[:[what][:[output][:[decorators][:output-options[,...]]]]]

-Xlog:directive

what
指定标签和级别的组合形式tag1[+tag2...][*][=level][,...]。除非指定通配符(*),否则只匹配与指定标签完全匹配的日志消息。请参阅-Xlog标签和级别
output
设置输出类型。省略output类型将默认为stdout。请参阅-Xlog输出
decorators
配置输出以使用自定义一组装饰器。省略decorators将默认为uptimeleveltags。请参阅装饰
output-options
设置-Xlog日志输出选项。
directive
全局选项或子命令:help、disable、async

描述

Java虚拟机(JVM)统一日志框架为JVM的所有组件提供了一个通用的日志系统。JVM的GC日志记录已更改为使用新的日志框架。旧GC标志到相应新Xlog配置的映射在将GC日志标志转换为Xlog中描述。此外,运行时日志记录也已更改为使用JVM统一日志框架。将传统运行时日志标志映射到相应新Xlog配置的映射在将运行时日志标志转换为Xlog中描述。

以下提供了-Xlog命令和选项的快速参考:

-Xlog
启用JVM日志记录,级别为info
-Xlog:help
打印-Xlog的用法语法和可用标签、级别和装饰器,以及带有解释的示例命令行。
-Xlog:disable
关闭所有日志记录并清除日志框架的所有配置,包括警告和错误的默认配置。
-Xlog[:option]

按照命令行上出现的顺序应用多个参数。相同输出的多个-Xlog参数会按照它们给定的顺序互相覆盖。

选项设置为:

[tag-selection][:[output][:[decorators][:output-options]]]

tag-selection将默认为标签集 all和级别 info

tag[+...] all

all标签是包含所有可用标签集的元标签。标签集定义中的星号*表示通配符标签匹配。使用通配符进行匹配会选择包含至少指定标签的所有标签集。没有通配符时,只选择与指定标签集完全匹配的标签集。

output-options

filecount=file-count filesize=带有可选K、M或G后缀的文件大小 foldmultilines=<true|false>

foldmultilines为true时,由多行组成的日志事件将通过将换行符替换为输出中的序列 '\''n'而折叠为单行。现有的单个反斜杠字符也将被替换为两个反斜杠的序列,以便可以反转转换。此选项可安全用于UTF-8字符编码,但其他编码可能无法正常工作。例如,它可能会错误地转换Shift JIS和BIG5中的多字节序列。

默认配置

-Xlog选项而没有其他内容时,将使用默认配置。默认配置记录所有级别匹配警告或错误的所有消息,而不管消息与哪些标签相关。默认配置等效于在命令行上输入以下内容:

-Xlog:all=warning:stdout:uptime,level,tags

在运行时控制日志记录

jcmd实用程序)在运行时控制日志记录。可以动态指定的所有内容都可以使用 VM.log命令动态指定。由于诊断命令自动公开为MBeans,因此可以使用JMX在运行时更改日志记录配置。

-Xlog标签和级别

gcjitos)。将GC标志映射到Xlog配置的描述在 将GC日志标志转换为Xlog中。将传统运行时日志标志映射到相应Xlog配置的描述在 将运行时日志标志转换为Xlog中。

可用日志级别:

  • off
  • trace
  • debug
  • info
  • warning
  • error

可用日志标签:

-Xlog:help查看所有可用日志标签。指定 all而不是标签组合将匹配所有标签组合。

-Xlog输出

-Xlog选项支持以下类型的输出:

  • stdout --- 发送输出到stdout
  • stderr --- 发送输出到stderr
  • file=filename --- 发送输出到文本文件。
file= filename时,在文件名中指定 %p和/或 %t将扩展为JVM的PID和启动时间戳。还可以配置文本文件以根据文件大小和要旋转的文件数进行文件旋转。例如,要每10 MB旋转一次日志文件并保留5个旋转文件,请指定选项 filesize=10M, filecount=5。文件的目标大小不能保证完全准确,只是一个近似值。默认情况下,文件会旋转,最多旋转5个目标大小为20 MB的文件,除非另有配置。指定 filecount=0表示不应旋转日志文件。有可能覆盖现有的日志文件。

-Xlog输出模式

-Xlog:async
将所有日志记录写入异步。

-XX:AsyncLogBufferSize=N指定中间缓冲区的内存预算(以字节为单位)。默认值应足够大,以满足大多数情况。如果需要,用户可以提供自定义值以在内存开销和日志准确性之间进行权衡。

装饰

日志消息装饰了有关消息的信息。您可以配置每个输出使用自定义的装饰器集。输出的顺序始终与表中列出的顺序相同。您可以在运行时配置要使用的装饰。装饰将添加到日志消息之前。例如:

[6.567s][info][gc,old] Old collection complete

省略decorators将默认为uptimeleveltags。特殊的none装饰器用于关闭所有装饰。

timet)、utctimeutc)、uptimeu)、timemillistm)、uptimemillisum)、timenanostn)、uptimenanosun)、hostnamehn)、pidp)、tidti)、levell)、tagstg)装饰器也可以指定为none以不进行装饰。

日志消息装饰
装饰 描述
timet ISO-8601格式的当前时间和日期。
utctimeutc 协调世界时或世界协调时间。
uptimeu JVM启动以来的时间(秒和毫秒)。例如,6.567秒。
timemillistm System.currentTimeMillis()生成的相同值。
uptimemillisum JVM启动后的毫秒数。
timenanostn System.nanoTime()生成的相同值。
uptimenanosun JVM启动后的纳秒数。
hostnamehn 主机名。
pidp 进程标识符。
tidti 线程标识符。
levell 与日志消息关联的级别。
tagstg 与日志消息关联的标签集。

将GC日志标志转换为Xlog

传统GC日志标志到Xlog配置映射
传统垃圾收集(GC)标志 Xlog配置 注释
G1PrintHeapRegions -Xlog:gc+region=trace 不适用
GCLogFileSize 无可用配置 日志轮换由框架处理。
NumberOfGCLogFiles 不适用 日志轮换由框架处理。
PrintAdaptiveSizePolicy -Xlog:gc+ergo*=level 对于大部分信息,使用leveldebug,或者对于PrintAdaptiveSizePolicy记录的所有内容,使用leveltrace
PrintGC -Xlog:gc 不适用
PrintGCApplicationConcurrentTime -Xlog:safepoint 请注意,PrintGCApplicationConcurrentTimePrintGCApplicationStoppedTime在新日志中记录在相同的标签上,并且没有分开。
PrintGCApplicationStoppedTime -Xlog:safepoint 请注意,PrintGCApplicationConcurrentTimePrintGCApplicationStoppedTime在新日志中记录在相同的标签上,并且没有分开。
PrintGCCause 不适用 GC原因现在始终被记录。
PrintGCDateStamps 不适用 日期戳由框架记录。
PrintGCDetails -Xlog:gc* 不适用
PrintGCID 不适用 GC ID现在始终被记录。
PrintGCTaskTimeStamps -Xlog:gc+task*=debug 不适用
PrintGCTimeStamps 不适用 时间戳由框架记录。
PrintHeapAtGC -Xlog:gc+heap=trace 不适用
PrintReferenceGC -Xlog:gc+ref*=debug 请注意,在旧日志中,只有在启用了PrintGCDetails时,PrintReferenceGC才会生效。
PrintStringDeduplicationStatistics `-Xlog:gc+stringdedup*=debug ` 不适用
PrintTenuringDistribution -Xlog:gc+age*=level 对于最相关信息,使用leveldebug,或者对于PrintTenuringDistribution记录的所有内容,使用leveltrace
UseGCLogFileRotation 不适用 对于PrintTenuringDistribution记录的内容。

将运行时日志标志转换为Xlog

这些传统标志不再被识别,如果直接使用将导致错误。请改用它们的统一日志等效项。

运行时日志标志到Xlog配置映射
传统运行时标志 Xlog配置 注释
TraceExceptions -Xlog:exceptions=info 不适用
TraceClassLoading -Xlog:class+load=level 使用level=info获取常规信息,或者使用level=debug获取额外信息。在统一日志语法中,-verbose:class等同于-Xlog:class+load=info,class+unload=info
TraceClassLoadingPreorder -Xlog:class+preorder=debug 不适用
TraceClassUnloading -Xlog:class+unload=level 使用level=info获取常规信息,或者使用level=trace获取额外信息。在统一日志语法中,-verbose:class等同于-Xlog:class+load=info,class+unload=info
VerboseVerification -Xlog:verification=info 不适用
TraceClassPaths -Xlog:class+path=info 不适用
TraceClassResolution -Xlog:class+resolve=debug 不适用
TraceClassInitialization -Xlog:class+init=info 不适用
TraceLoaderConstraints -Xlog:class+loader+constraints=info 不适用
TraceClassLoaderData -Xlog:class+loader+data=level 使用level=debug获取常规信息,或者使用level=trace获取额外信息。
TraceSafepointCleanupTime -Xlog:safepoint+cleanup=info 不适用
TraceSafepoint -Xlog:safepoint=debug 不适用
TraceMonitorInflation -Xlog:monitorinflation=debug 不适用
TraceRedefineClasses -Xlog:redefine+class*=level level=infodebugtrace提供逐渐增加的信息量。

-Xlog 使用示例

以下是-Xlog的示例。

-Xlog

使用info级别将所有消息记录到stdout,并带有uptimelevelstags装饰。这等同于使用:

-Xlog:all=info:stdout:uptime,levels,tags

-Xlog:gc
使用info级别将带有gc标记的消息记录到stdout。对于所有其他消息,默认配置为warning级别。
-Xlog:gc,safepoint
使用info级别将带有gcsafepoint标记的消息记录到stdout,带有默认装饰。带有gcsafepoint标记的消息不会被记录。
-Xlog:gc+ref=debug
使用debug级别将带有gcref标记的消息记录到stdout,带有默认装饰。只带有这两个标记中的一个的消息不会被记录。
-Xlog:gc=debug:file=gc.txt:none
使用debug级别将带有gc标记的消息记录到名为gc.txt的文件中,不带装饰。对于所有其他消息,默认配置为warning级别。
-Xlog:gc=trace:file=gctrace.txt:uptimemillis,pids:filecount=5,filesize=1024

使用trace级别将带有gc标记的消息记录到一个包含5个大小为1 MB的旋转文件集中,基本名称为gctrace.txt,并使用uptimemillispid装饰。

对于所有其他消息,默认配置为warning级别。

-Xlog:gc::uptime,tid
使用默认的info级别将带有gc标记的消息记录到默认的stdout中,并使用uptimetid装饰。对于所有其他消息,默认配置为warning级别。
-Xlog:gc*=info,safepoint*=off
使用info级别将至少带有gc标记的消息记录,但关闭带有safepoint标记的消息记录。带有gcsafepoint标记的消息不会被记录。
-Xlog:disable -Xlog:safepoint=trace:safepointtrace.txt
关闭所有记录,包括警告和错误,然后启用带有safepoint标记的消息使用trace级别记录到名为safepointtrace.txt的文件中。默认配置不适用,因为命令行以-Xlog:disable开头。

复杂 -Xlog 使用示例

以下描述了使用-Xlog选项的一些复杂示例。

-Xlog:gc+class*=debug
使用debug级别将至少带有gcclass标记的消息记录到stdout。对于所有其他消息,默认配置为warning级别。
-Xlog:gc+meta*=trace,class*=off:file=gcmetatrace.txt
使用trace级别将至少带有gcmeta标记的消息记录到名为metatrace.txt的文件中,但关闭所有带有class标记的消息记录。带有gcmetaclass标记的消息不会被记录,因为class*被设置为关闭。对于所有其他消息,默认配置为warning级别,除了包含class的消息。
-Xlog:gc+meta=trace
使用trace级别将仅带有gcmeta标记的消息记录到stdout。对于所有其他消息,默认配置为warning级别。
-Xlog:gc+class+heap*=debug,meta*=warning,threads*=off
使用trace级别将至少带有gcclassheap标记的消息记录到stdout,但仅记录带有meta标记的消息。对于所有其他消息,默认配置为warning级别,除了包含threads的消息。

验证Java虚拟机标志参数

您可以使用所有Java虚拟机(JVM)命令行标志提供的值进行验证,如果输入值无效或超出范围,则会显示适当的错误消息。

无论是通过人体工程学设置、命令行、输入工具还是通过API(例如包含在java.lang.management包中的类)提供的值,都会对所有Java虚拟机(JVM)命令行标志提供的值进行验证。人体工程学在Java平台标准版HotSpot虚拟机垃圾回收调整指南中有描述。

在JVM初始化期间设置所有标志的值或在运行时更改标志的值(例如使用jcmd工具)时,范围和约束将得到验证。如果值违反范围或约束检查,则JVM将终止,并在错误流上打印适当的错误消息。

例如,如果标志违反范围或约束检查,则JVM将以错误退出:

java -XX:AllocatePrefetchStyle=5 -version
intx AllocatePrefetchStyle=5 is outside the allowed range [ 0 ... 3 ]
Improperly specified VM option 'AllocatePrefetchStyle=5'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

标志-XX:+PrintFlagsRanges打印所有标志的范围。此标志允许通过范围提供的值自动测试标志。对于具有指定范围的标志,输出中打印了类型、名称和实际范围。

例如,

intx   ThreadStackSize [ 0 ... 9007199254740987 ] {pd product}

对于没有指定范围的标志,值不会在打印输出中显示。例如:

size_t NewSize         [   ...                  ] {product}

这有助于识别需要实现的标志。自动测试框架可以跳过那些没有值且未实现的标志。

大页

您可以使用大页,也称为巨大页,作为比标准内存页大小(取决于处理器和操作系统)大得多的内存页。大页优化处理器的转换查找缓存。

转换查找缓存(TLB)是一个页面转换缓存,保存最近使用的虚拟地址到物理地址的转换。TLB是一种稀缺的系统资源。TLB未命中可能很昂贵,因为处理器必须然后从分层页表中读取,这可能需要多次内存访问。通过使用更大的内存页大小,单个TLB条目可以表示更大的内存范围。这减轻了对TLB的压力,内存密集型应用程序可能会有更好的性能。

然而,使用大页可能会对系统性能产生负面影响。例如,当应用程序固定了大量内存时,可能会导致常规内存短缺,并导致其他应用程序过度分页,从而减慢整个系统的速度。此外,长时间运行的系统可能会产生过多的碎片,这可能会使无法保留足够的大页内存。当发生这种情况时,操作系统或JVM将回退到使用常规页。

Linux和Windows支持大页。

Linux的大页支持

Linux自2.6版本起支持大页。要检查您的环境是否支持大页,请尝试以下操作:

# cat /proc/meminfo | grep Huge
HugePages_Total: 0
HugePages_Free: 0
...
Hugepagesize: 2048 kB

如果输出包含以“Huge”为前缀的项目,则您的系统支持大页。值可能会根据环境而异。 Hugepagesize字段显示您的环境中的默认大页大小,其他字段显示此大小的大页的详细信息。更新的内核支持多个大页大小。要列出支持的页大小,请运行以下命令:

# ls /sys/kernel/mm/hugepages/
hugepages-1048576kB  hugepages-2048kB

上述环境支持2 MB和1 GB的大页,但需要配置它们以便JVM可以使用它们。当使用大页并且未启用透明大页(选项-XX:+UseTransparentHugePages)时,必须预先分配大页的数量。例如,要启用由2 MB大页支持的8 GB内存,请以root身份登录并运行:

# echo 4096 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

始终建议在请求后检查nr_hugepages的值,以确保内核能够分配请求的大页数量。

当使用选项-XX:+UseSHM启用大页时,还需要确保SHMMAX参数已配置为允许分配足够大的共享内存段。要允许最大共享段为8 GB,请以root身份登录并运行:

# echo 8589934592 > /proc/sys/kernel/shmmax

在某些环境中,这是不需要的,因为默认值已足够大,但重要的是确保值足够大,以适应打算由大页支持的内存量。

注意:在重新启动系统后,/proc/sys中包含的值会重置,因此可能需要在初始化脚本(例如rc.localsysctl.conf)中设置它们。

如果配置操作系统内核参数以启用大页的使用,Java进程可能会为Java堆以及其他内部区域(例如)分配大页:

  • 代码缓存
  • 标记位图

因此,如果将nr_hugepages参数配置为Java堆的大小,则JVM仍可能无法使用大页来分配堆,因为其他区域(例如代码缓存)可能已经使用了一些配置的大页。

Windows的大页支持

要在Windows上使用大页支持,管理员必须首先为运行应用程序的用户分配额外的特权:

  1. 选择控制面板管理工具,然后选择本地安全策略
  2. 选择本地策略,然后选择用户权限分配
  3. 双击锁定内存页,然后添加用户和/或组。
  4. 重新启动系统。

请注意,即使是管理员运行应用程序,也需要执行这些步骤,因为默认情况下管理员没有锁定内存页的特权。

应用程序类数据共享

应用程序类数据共享(AppCDS)将应用程序使用的类存储在存档文件中。由于这些类存储在可以比从JAR文件加载的类更快加载的格式中,AppCDS可以提高应用程序的启动时间。此外,AppCDS可以通过在多个进程之间共享这些类的部分来减少运行时内存占用。

CDS存档中的类以优化格式存储,大约比存储在JAR文件或JDK运行时映像中的类大2到5倍。因此,最好仅存档实际应用程序使用的那些类。通常,这些类仅是所有可用类的一小部分。例如,您的应用程序可能仅使用大型库提供的少量API。

使用CDS存档

默认情况下,在大多数JDK发行版中,除非指定了-Xshare:off,JVM将使用默认的CDS存档启动,通常位于JAVA_HOME/lib/server/classes.jsa(或Windows上的JAVA_HOME\bin\server\classes.jsa)。此存档包含大约1300个核心库类,大多数应用程序都会使用这些类。

要为应用程序使用的确切类集使用CDS,可以使用-XX:SharedArchiveFile选项,其一般形式为:

-XX:SharedArchiveFile=<static_archive>:<dynamic_archive>

  • <static_archive>覆盖默认的CDS存档。
  • <dynamic_archive>提供可以加载在<static_archive>之上的其他类。
  • 在Windows上,上述路径分隔符:应替换为;

(“static”和“dynamic”这些名称出于历史原因而使用。唯一的意义是“static”存档首先加载,“dynamic”存档其次加载)。

JVM最多可以使用两个存档。要仅使用单个<static_archive>,可以省略<dynamic_archive>部分:

-XX:SharedArchiveFile=<static_archive>

为方便起见,<dynamic_archive>记录了<static_archive>的位置。因此,您可以仅指定<dynamic_archive>而省略<static_archive>

-XX:SharedArchiveFile=<dynamic_archive>

手动创建CDS存档

可以使用几种方法手动创建CDS存档:

  • -Xshare:dump
  • -XX:ArchiveClassesAtExit
  • jcmd VM.cds

所有这些方法中的一个常见操作是“试运行”,其中您运行应用程序一次以确定应存储在存档中的类。

使用-Xshare:dump创建静态CDS存档文件

以下步骤创建一个包含test.Hello应用程序使用的所有类的静态CDS存档文件。

  1. 创建test.Hello应用程序使用的所有类的列表。以下命令创建一个名为hello.classlist的文件,其中包含此应用程序使用的所有类的列表:

    java -Xshare:off -XX:DumpLoadedClassList=hello.classlist -cp hello.jar test.Hello

    -cp参数指定的类路径必须仅包含JAR文件。

  2. 创建一个名为hello.jsa的静态存档,其中包含hello.classlist中的所有类:

    java -Xshare:dump -XX:SharedArchiveFile=hello.jsa -XX:SharedClassListFile=hello.classlist -cp hello.jar

  3. 使用存档hello.jsa运行应用程序test.Hello

    java -XX:SharedArchiveFile=hello.jsa -cp hello.jar test.Hello

  4. 可选 验证test.Hello应用程序是否使用hello.jsa共享存档中包含的类:

    java -XX:SharedArchiveFile=hello.jsa -cp hello.jar -Xlog:class+load test.Hello

    此命令的输出应包含以下文本:

    [info][class,load] test.Hello source: shared objects file

使用-XX:ArchiveClassesAtExit创建动态CDS存档文件

动态CDS存档的优点包括:

  • 它们通常使用更少的磁盘空间,因为它们不需要存储已经在静态存档中的类。
  • 与可比较的静态存档相比,它们创建时少了一个步骤。

以下步骤创建一个动态CDS存档文件,其中包含由test.Hello应用程序使用的类,但不包括默认CDS存档中已经存在的类。

  1. 创建一个名为hello.jsa的动态CDS存档,其中包含由应用程序test.Hello加载的hello.jar中的所有类:

    java -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello

  2. 使用共享存档hello.jsa运行应用程序test.Hello

    java -XX:SharedArchiveFile=hello.jsa -cp hello.jar test.Hello

  3. 可选 重复上一节的第4步,验证test.Hello应用程序是否使用hello.jsa共享存档中包含的类。

还可以使用非默认静态CDS存档创建动态CDS存档。例如,

java -XX:SharedArchiveFile=base.jsa -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello

要使用此动态CDS存档运行应用程序:

java -XX:SharedArchiveFile=base.jsa;hello.jsa -cp hello.jar Hello

(在Windows上,上述路径分隔符:应替换为;

如上所述,静态存档的名称可以被省略:

java -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello

使用jcmd创建CDS存档文件

前两节需要您修改应用程序的启动脚本以创建CDS存档。有时这可能很困难,例如,如果应用程序的类路径是通过复杂的例程设置的。

jcmd VM.cds命令提供了一种较少侵入性的方式,通过连接到运行中的JVM进程来创建CDS存档。您可以创建静态存档:

jcmd <pid> VM.cds static_dump my_static_archive.jsa

或动态存档:

jcmd <pid> VM.cds dynamic_dump my_dynamic_archive.jsa

要在后续运行应用程序时使用生成的存档文件而无需修改应用程序的启动脚本,您可以使用以下技术:

env JAVA_TOOL_OPTIONS=-XX:SharedArchiveFile=my_static_archive.jsa bash app_start.sh

注意:要使用jcmd <pid> VM.cds dynamic_dump,必须使用-XX:+RecordDynamicDumpInfo启动由<pid>标识的JVM进程,这也可以通过相同的技术传递给应用程序启动脚本:

env JAVA_TOOL_OPTIONS=-XX:+RecordDynamicDumpInfo bash app_start.sh

使用-XX:+AutoCreateSharedArchive创建动态CDS存档文件

-XX:+AutoCreateSharedArchive是创建/使用CDS存档的更便捷方式。与前一节中描述的手动创建CDS存档的方法不同,使用-XX:+AutoCreateSharedArchive,不再需要单独的试运行。相反,您可以始终使用相同的命令行运行应用程序,并自动享受CDS的好处。

java -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello

如果指定的存档文件存在且是由相同版本的JDK创建的,则它将被加载为动态存档;否则在VM启动时将被忽略。

在VM退出时,如果指定的存档文件不存在,它将被创建。如果存在但是由不同(但是JDK 19之后的)版本的JDK创建,则将被替换。在这两种情况下,存档将准备好在下次使用相同命令行启动JVM时加载。

如果指定的存档文件存在但是由JDK 19之前的版本创建,则将被忽略:在启动时不加载,退出时不替换。

开发人员应注意,CDS存档文件的内容对每个JDK版本的构建是特定的。因此,如果切换到不同的JDK构建,-XX:+AutoCreateSharedArchive将自动重新创建存档以匹配JDK。如果您打算将此功能与现有存档一起使用,您应确保存档由至少JDK 19版本创建。

类路径和模块路径的限制

  • 类路径(-classpath-Xbootclasspath/a)和模块路径(--module-path)都不能包含非空目录。

  • --module-path中仅支持模块化JAR文件。不支持已解压的模块。

  • 在创建存档时使用的类路径必须与运行时使用的类路径相同(或是其前缀)。(对于模块路径,没有这样的要求。)

  • 如果在生成存档后修改了类路径或模块路径中的任何JAR文件,则无法加载CDS存档。

  • 如果指定了任何VM选项--upgrade-module-path--patch-module--limit-modules,则CDS将被禁用。这意味着JVM将在不加载任何CDS存档的情况下执行。此外,如果尝试使用这3个选项之一创建CDS存档,JVM将报告错误。

性能调优示例

您可以使用Java高级运行时选项来优化应用程序的性能。

调优以提高吞吐量

使用以下命令和高级选项来实现应用程序的更高吞吐量性能:

java -server -XX:+UseParallelGC -XX:+UseLargePages -Xmn10g -Xms26g -Xmx26g

调优以降低响应时间

使用以下命令和高级选项来实现应用程序的更低响应时间:

java -XX:+UseG1GC -XX:MaxGCPauseMillis=100

保持Java堆较小并减少嵌入式应用程序的动态占用空间

使用以下高级运行时选项来保持Java堆较小并减少嵌入式应用程序的动态占用空间:

-XX:MaxHeapFreeRatio=10 -XX:MinHeapFreeRatio=5

注意:这两个选项的默认值分别为70%和40%。由于使用这些较小的设置可能会导致性能损失,您应该通过尽可能减少这些设置来优化小占用空间,而不会引入不可接受的性能降级。

退出状态

当启动器使用错误参数、严重错误或JVM抛出异常时,通常会返回以下退出值。但是,Java应用程序可以通过使用API调用System.exit(exitValue)返回任何值。这些值为:

  • 0:成功完成

  • >0:发生错误