_JAVA_OPTIONS、JAVA_TOOL_OPTIONS和JAVA_OPTS之间的区别是什么?

247

我认为对比_JAVA_OPTIONSJAVA_TOOL_OPTIONS会很有意义。我已经搜索了一些内容,但是没有找到任何有用的信息,所以我希望我们可以在Stackoverflow上找到答案。

JAVA_OPTS仅仅是用于完整性考虑,它不是JVM的一部分,但在外部有很多关于它的问题。

目前我所知道的:

到目前为止,我发现:

  • JAVA_OPTS不被JDK使用,但被许多其他应用程序使用(请参见该帖子)。
  • JAVA_TOOL_OPTIONS_JAVA_OPTIONS是将JVM参数指定为环境变量而不是命令行参数的方法。
    • 它们至少被javajavac识别
    • 它们具有以下优先级:
      1. _JAVA_OPTIONS(覆盖其他选项)
      2. 命令行参数
      3. JAVA_TOOL_OPTIONS(被其他选项覆盖)

我想了解的内容

  • 是否有任何官方文档比较JAVA_TOOL_OPTIONS_JAVA_OPTIONS
  • JAVA_TOOL_OPTIONS_JAVA_OPTIONS之间是否有其他差异(除了优先级)。
  • 哪些可执行文件除了javajavac之外还可以选择JAVA_TOOL_OPTIONS_JAVA_OPTIONS
  • JAVA_TOOL_OPTIONS_JAVA_OPTIONS中是否有任何限制?

官方文档

我没有找到任何关于_JAVA_OPTIONS的文档。有关JAVA_TOOL_OPTIONS的文档并没有详细说明它们之间的区别:

由于并不总是能够访问或修改命令行,例如在嵌入式VM中或仅深度脚本中启动的VM中,因此提供了JAVA_TOOL_OPTIONS变量,以便在这些情况下启动代理。
...

示例脚本

这是我用来找出这个问题的代码。控制台输出包含在注释中:

export JAVA_OPTS=foobar
export JAVA_TOOL_OPTIONS= 
export _JAVA_OPTIONS="-Xmx512m -Xms64m"

java -version                          
# Picked up JAVA_TOOL_OPTIONS: 
# Picked up _JAVA_OPTIONS: -Xmx512m -Xms64m
# java version "1.7.0_40"
OpenJDK Runtime Environment (IcedTea 2.4.1) (suse-3.41.1-x86_64)
OpenJDK 64-Bit Server VM (build 24.0-b50, mixed mode)

javac -version
# Picked up JAVA_TOOL_OPTIONS: 
# Picked up _JAVA_OPTIONS: -Xmx512m -Xms64m
# javac 1.7.0_40

export JAVA_TOOL_OPTIONS="-Xmx1 -Xms1"
export _JAVA_OPTIONS="-Xmx512m -Xms64m"
javac -version
# Picked up JAVA_TOOL_OPTIONS: -Xmx1 -Xms1
# Picked up _JAVA_OPTIONS: -Xmx512m -Xms64m
# javac 1.7.0_40

export JAVA_TOOL_OPTIONS="-Xmx512m -Xms64m"
export _JAVA_OPTIONS="-Xmx1 -Xms1"
javac -version
# Picked up JAVA_TOOL_OPTIONS: -Xmx512m -Xms64m
# Picked up _JAVA_OPTIONS: -Xmx1 -Xms1
# Error occurred during initialization of VM
# Too small initial heap

export JAVA_TOOL_OPTIONS="-Xmx1 -Xms1"
export _JAVA_OPTIONS=
java -Xmx512m -Xms64m -version
# Picked up JAVA_TOOL_OPTIONS: -Xmx1 -Xms1
# Picked up _JAVA_OPTIONS: 
# java version "1.7.0_40"
# OpenJDK Runtime Environment (IcedTea 2.4.1) (suse-3.41.1-x86_64)
# OpenJDK 64-Bit Server VM (build 24.0-b50, mixed mode)

export JAVA_TOOL_OPTIONS=
export _JAVA_OPTIONS="-Xmx1 -Xms1"
java -Xmx512m -Xms64m -version
# Picked up JAVA_TOOL_OPTIONS: 
# Picked up _JAVA_OPTIONS: -Xmx1 -Xms1
# Error occurred during initialization of VM
# Too small initial heap

2
请提供有关Java选项的信息。 - user180100
9
自从JDK 9+版本以来,JDK_JAVA_OPTIONS已成为首选替代项,请参阅https://dev59.com/JVQJ5IYBdhLWcg3w2Jm8。 - ryenus
3个回答

104
您几乎已经掌握了要点,除了这些选项即使通过库调用启动JVM时也会被捕获。没有文档说明 _JAVA_OPTIONS 这个变量不建议使用,我确实看到有人滥用它在他们的~/.bashrc中设置它。然而,如果想深入了解此问题,可以检查Oracle HotSpot VM的源代码(例如在OpenJDK7中)。您还应该记住,没有保证其他VM具有或将继续支持未记录的变量。更新2015-08-04:为了为来自搜索引擎的人节省五分钟时间,_JAVA_OPTIONS 覆盖命令行参数,反过来又覆盖 JAVA_TOOL_OPTIONS

15
作为非英语为母语的人,"_JAVA_OPTIONS优先于命令行参数,而命令行参数又优先于JAVA_TOOL_OPTIONS"这句话很难理解。意思是在Java应用程序中,如果设置了"_JAVA_OPTIONS"环境变量,它将比命令行上指定的Java选项优先级更高;同样地,命令行选项比"JAVA_TOOL_OPTIONS"环境变量的值具有更高的优先级。 - yang yang
11
在这个语境下,“trumps”的意思是“优先于”。因此,如果_JAVA_OPTIONS="-Dfoo=bar",而JAVA_TOOL_OPTIONS="-Dfoo=sna",最终的结果是System.getProperty("foo")将返回"bar"。 - DanM

65

还有一个区别: _JAVA_OPTIONS 是Oracle特定的。IBM JVM使用IBM_JAVA_OPTIONS 代替。这可能是为了定义机器特定选项而不发生冲突。JAVA_TOOL_OPTIONS被所有VMs识别。


43

JAVA_OPTS在JVM中没有任何特殊处理。

根据https://bugs.openjdk.java.net/browse/JDK-4971166JAVA_TOOL_OPTIONS被包含在标准JVMTI规范中,对带引号的空格有更好的处理方式,并且应始终优先使用它,而不是未经记录的Hotspot-specific _JAVA_OPTIONS

还要注意,使用这些选项会输出无法抑制的额外消息到stdout。


正如 @ryenus 所指出的,自 JDK 9+ 开始,JDK_JAVA_OPTIONS 环境变量成为首选替代方案,请参见 在使用Java 11时,JDK_JAVA_OPTIONS和JAVA_TOOL_OPTIONS有什么区别?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接