Diferença entre _JAVA_OPTIONS, JAVA_TOOL_OPTIONS e JAVA_OPTS

151

Eu pensei que seria ótimo ter uma comparação entre _JAVA_OPTIONSe JAVA_TOOL_OPTIONS. Eu tenho procurado um pouco, mas não consigo encontrar nada, então espero que possamos encontrar o conhecimento aqui no Stackoverflow.

JAVA_OPTSestá incluído para ser completo. Não faz parte da JVM, mas há muitas perguntas sobre isso na natureza.

O que eu sei:

Até agora eu descobri que:

  • JAVA_OPTSnão é usado pelo JDK, mas por vários outros aplicativos (consulte esta publicação ).
  • JAVA_TOOL_OPTIONSe _JAVA_OPTIONSsão maneiras de especificar argumentos da JVM como uma variável de ambiente em vez de parâmetros da linha de comandos.
    • Os são apanhados por pelo menos javaejavac
    • Eles têm esta precedência:
      1. _JAVA_OPTIONS (substitui os outros)
      2. Parâmetros da linha de comando
      3. JAVA_TOOL_OPTIONS (é sobrescrito pelos outros)

O que eu gostaria de saber

  • Existe alguma documentação oficial comparando JAVA_TOOL_OPTIONSe_JAVA_OPTIONS
  • Existem outras diferenças entre JAVA_TOOL_OPTIONSe _JAVA_OPTIONS(exceto a precedência).
  • Quais executáveis ​​pegam JAVA_TOOL_OPTIONSe _JAVA_OPTIONS(além de javae javac)
  • Qualquer limitação sobre o que pode ser incluído JAVA_TOOL_OPTIONSe_JAVA_OPTIONS

Documentação oficial

Não consegui encontrar nenhuma documentação sobre _JAVA_OPTIONS. A documentação paraJAVA_TOOL_OPTIONS não lança muita luz sobre a diferença:

Como a linha de comando nem sempre pode ser acessada ou modificada, por exemplo, em VMs incorporadas ou simplesmente VMs ativadas profundamente nos scripts, uma variável JAVA_TOOL_OPTIONS é fornecida para que os agentes possam ser ativados nesses casos.
...

Script de exemplo

Este é o código que eu usei para descobrir isso. A saída do console está incluída como comentários:

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
Tobber
fonte
3
E desde JDK 9 + , não há JDK_JAVA_OPTIONScomo o substituto preferido, consulte stackoverflow.com/q/52986487/537554
ryenus

Respostas:

62

Você acertou bastante, exceto que essas opções são selecionadas mesmo se você iniciar a JVM em processo por meio de uma chamada de biblioteca.

O fato de _JAVA_OPTIONSnão estar documentado sugere que não é recomendado o uso dessa variável, e eu realmente vi pessoas abusando dela, definindo-a na sua ~/.bashrc. No entanto, se você quiser chegar ao fundo desse problema, poderá verificar a fonte do Oracle HotSpot VM (por exemplo, no OpenJDK7 ).

Você também deve se lembrar de que não há garantia de que outras VMs tenham ou continuem a ter suporte para variáveis ​​não documentadas.

ATUALIZAÇÃO 04-08-2015: para economizar cinco minutos para pessoas provenientes de mecanismos de pesquisa, _JAVA_OPTIONSsupera os argumentos da linha de comando, que por sua vez superam JAVA_TOOL_OPTIONS.

mkalkov
fonte
36

Há mais uma diferença: _JAVA_OPTIONSé específico do Oracle. O IBM JVM está usando em seu IBM_JAVA_OPTIONSlugar. Provavelmente, isso foi feito para poder definir opções específicas da máquina sem colisões. JAVA_TOOL_OPTIONSé reconhecido por todas as VMs.

Victor Havin
fonte
21

JAVA_OPTSnão tem nenhum tratamento especial na JVM.

E de acordo com https://bugs.openjdk.java.net/browse/JDK-4971166 o JAVA_TOOL_OPTIONSestá incluído na especificação padrão JVMTI, faz melhor gestão do espaço cotados e deve ser sempre preferido em vez de específica Hotspot-indocumentados _JAVA_OPTIONS.

Lembre-se também de que o uso dessas impressões imprime mensagens adicionais no stdout que não podem ser suprimidas .


Como observou @ryenus, desde o JDK 9+, há JDK_JAVA_OPTIONS como a substituição preferida, consulte Qual é a diferença entre JDK_JAVA_OPTIONS e JAVA_TOOL_OPTIONS ao usar o Java 11?

Vadzim
fonte