JDK_JAVA_OPTIONS 和 JAVA_TOOL_OPTIONS 有什麼不同?
1. 概述
在配置 Java 應用程式時,我們經常需要傳遞 JVM 選項而不修改腳本。我們可以使用環境變數JDK_JAVA_OPTIONS
或JAVA_TOOL_OPTIONS.
而不必每次執行java
命令時手動新增標誌。這兩個環境變數具有相同的用途 - 動態傳遞 JVM 選項 - 但它們的工作方式不同。
在本教程中,我們將探討它們的差異、何時使用它們以及有效管理 JVM 配置的最佳實踐。
2.什麼是JDK_JAVA_OPTIONS
和JAVA_TOOL_OPTIONS
?
這兩個環境變數都允許我們全域指定 JVM 選項,因此不需要在每次執行 JDK 工具(例如java
、 javac, javadoc
,
)時修改選項。
JAVA_TOOL_OPTIONS
是在 Java 5 中引入的**JDK_JAVA_OPTIONS
**
在深入了解每個變數如何發揮作用之前,讓我們先建立一個簡單的 Java 原始檔:
package com.baeldung;
/**
* A simple class to print some variables' value
*/
public class TestEnvVar {
public static void main (String[] args){
System.out.println("var1 = '" + System.getProperty("var1") + "'");
System.out.println("var2 = '" + System.getProperty("var2") + "'");
}
}
上面的程式碼非常簡單。我們的main()
方法印出var1
和var2的值。稍後,我們將使用這兩個環境變數將這個參數傳遞給該類別。
接下來我們來編譯程式碼:
$ javac com/baeldung/TestEnvVar.java
現在,我們有以下文件結構:
$ tree
.
└── com
└── baeldung
├── TestEnvVar.class
└── TestEnvVar.java
3 directories, 1 file
順便說一下,我們將使用 Java 23 在 Linux 上編譯或運行本教程中的所有範例:
$ java -version
openjdk version "23.0.1" 2024-10-15
OpenJDK Runtime Environment Homebrew (build 23.0.1)
OpenJDK 64-Bit Server VM Homebrew (build 23.0.1, mixed mode, sharing)
接下來,讓我們運行該類別並將一些值傳遞給所需的變數。
3. 執行 Java 啟動器 – java
指令
啟動 Java 程式的典型方法是使用 Java 啟動器 - java
命令。
首先,讓我們在JDK_JAVA_OPTIONS
中定義var1
和var2
並啟動我們的main()
方法:
$ JDK_JAVA_OPTIONS="-Dvar1='Hello (JDK_JAVA_OPTIONS)' -Dvar2='World (JDK_JAVA_OPTIONS)'" java com.baeldung.TestEnvVar
NOTE: Picked up JDK_JAVA_OPTIONS: -Dvar1='Hello (JDK_JAVA_OPTIONS)' -Dvar2='World (JDK_JAVA_OPTIONS)'
var1 = 'Hello (JDK_JAVA_OPTIONS)'
var2 = 'World (JDK_JAVA_OPTIONS)'
如輸出所示, java
指令讀取JDK_JAVA_OPTIONS
變數並將var1
和var2
的值傳遞給main()
方法,產生預期結果。此外, java
輸出一則訊息通知我們已選取JDK_JAVA_OPTIONS
。
值得注意的是,我們在同一行設定環境變數並執行java
指令,中間用空格隔開。這確保JDK_JAVA_OPTIONS
僅為特定的java
指令設定。如果我們在運行命令後檢查變量,我們會發現JDK_JAVA_OPTIONS
不再具有值:
$ echo $JDK_JAVA_OPTIONS
現在,讓我們在JAVA_TOOL_OPTIONS
中設定var1
和var2
並運行我們的類別:
$ JAVA_TOOL_OPTIONS="-Dvar1='Hi (JAVA_TOOL_OPTIONS)' -Dvar2='There (JAVA_TOOL_OPTIONS)'" java com.baeldung.TestEnvVar
Picked up JAVA_TOOL_OPTIONS: -Dvar1='Hi (JAVA_TOOL_OPTIONS)' -Dvar2='There (JAVA_TOOL_OPTIONS)'
var1 = 'Hi (JAVA_TOOL_OPTIONS)'
var2 = 'There (JAVA_TOOL_OPTIONS)'
類似地, JAVA_TOOL_OPTIONS
變數會影響 Java 啟動器。此外,類似的訊息告訴我們java
指令讀取JAVA_TOOL_OPTIONS.
現在,有些人可能想知道:如果在JDK_JAVA_OPTIONS
和JAVA_TOOL_OPTIONS?
哪一個優先?接下來我們來測試一下:
$ JAVA_TOOL_OPTIONS="-Dvar1='Hi (JAVA_TOOL_OPTIONS)' -Dvar2='There (JAVA_TOOL_OPTIONS)'" JDK_JAVA_OPTIONS="-Dvar2='World (by JDK_JAVA_OPTIONS)'" java com.baeldung.TestEnvVar
NOTE: Picked up JDK_JAVA_OPTIONS: -Dvar2='World (by JDK_JAVA_OPTIONS)'
Picked up JAVA_TOOL_OPTIONS: -Dvar1='Hi (JAVA_TOOL_OPTIONS)' -Dvar2='There (JAVA_TOOL_OPTIONS)'
var1 = 'Hi (JAVA_TOOL_OPTIONS)'
var2 = 'World (by JDK_JAVA_OPTIONS)'
在這個例子中,我們在JAVA_TOOL_OPTIONS
中定義了var1
和var2
,但在JDK_JAVA_OPTIONS
中只定義了不同值的var2
。輸出顯示java
選擇了兩個環境變數。但是,如果在JDK_JAVA_OPTIONS
和JAVA_TOOL_OPTIONS
中設定了相同的變量,則JDK_JAVA_OPTIONS
優先。
4.其他Java命令
除了java
命令之外,JDK 還提供了其他幾個命令,使我們能夠有效地編譯、記錄和管理 Java 應用程序,例如:
-
javac
– Java 編譯器 -
javadoc
– JavaDoc 生成器 - 以及更多
接下來,讓我們弄清楚這些工具如何處理JDK_JAVA_OPTIONS
和JAVA_TOOL_OPTIONS.
我們將以javac
編譯器為例。與java
指令不同,透過javac
檢查變數值並不簡單。因此,為了測試其行為,我們將在JDK_JAVA_OPTIONS
和JAVA_TOOL_OPTIONS
中設定最大堆大小( -Xmx
)JVM 參數,並驗證它是否如預期般影響javac
。
首先,讓我們檢查javac
的預設MaxHeapSize
值:
$ javac -J-XX:+PrintCommandLineFlags com/baeldung/TestEnvVar.java
... -XX:MaxHeapSize=9663676416 ...
在此範例中, -J-XX:+PrintCommandLineFlags
選項與某些 JDK 工具(在本例中javac
)一起使用,以列印出工具啟動時 JVM 正在使用的命令列標誌。
如輸出所示,在這台機器上,JVM 將 9GiB( 9*1024*1024*1024=9663676416 Bytes
)記憶體作為預設的MaxHeapSize.
接下來,讓我們將JAVA_TOOL_OPTIONS
中的MaxHeapSize
設定為 10MiB( 10*1024*1024 = 10485760
位元組),然後再次編譯原始檔:
$ JAVA_TOOL_OPTIONS="-Xmx10m" javac -J-XX:+PrintCommandLineFlags com/baeldung/TestEnvVar.java
Picked up JAVA_TOOL_OPTIONS: -Xmx10m
... -XX:MaxHeapSize=10485760 ...
如輸出所示, JAVA_TOOL_OPTIONS
會影響javac
。
接下來,讓我們用JDK_JAVA_OPTIONS
來做同樣的測試 多變的:
$ JDK_JAVA_OPTIONS="-Xmx10m" javac -J-XX:+PrintCommandLineFlags com/baeldung/TestEnvVar.java
... -XX:MaxHeapSize=9663676416 ...
事實證明**JDK_JAVA_OPTIONS
並不影響javac.
**它仍然使用預設選項編譯原始檔: MaxHeapSize=9GiB.
事實上,這不僅僅是javac.
它適用於除**java**
命令**之外的所有 JDK 工具——**僅**識別****JAVA_TOOL_OPTIONS**
。
接下來我們使用另一個JDK工具javadoc
指令來驗證一下:
$ JAVA_TOOL_OPTIONS="-Xmx10m" javadoc -J-XX:+PrintCommandLineFlags com/baeldung/TestEnvVar.java
Picked up JAVA_TOOL_OPTIONS: -Xmx10m
... -XX:MaxHeapSize=10485760 ...
$ JDK_JAVA_OPTIONS="-Xmx10m" javadoc -J-XX:+PrintCommandLineFlags com/baeldung/TestEnvVar.java | sed 's/ /\n/g' | grep MaxHeapSize
Loading source file com/baeldung/TestEnvVar.java...
... -XX:MaxHeapSize=9663676416 ...
我們可以看到,該命令忽略了JDK_JAVA_OPTIONS
中設定的-Xmx10m
參數,但正確識別了JAVA_TOOL_OPTIONS
變數中的值。
5. JDK_JAVA_OPTIONS
與JAVA_TOOL_OPTIONS
到目前為止,我們討論了這兩個環境變數如何與 JDK 工具配合使用。接下來,為了讓大家有清楚的了解,我們來用表格來總結差異:
JAVA_TOOL_OPTIONS | JDK_JAVA_OPTIONS | |
---|---|---|
目的 | 環境變數將 JVM 選項和參數傳遞給 JDK 工具 | 環境變數將 JVM 選項和參數傳遞給 Java 啟動器以啟動 Java 應用程式 |
範圍 | 它影響所有 JDK 工具(java, javac, javadoc, jar, 等) |
它僅影響java 命令 |
作品 | Java 5+ | Java 9+ |
Java 啟動器的優先權 | JDK_JAVA_OPTIONS 中的值會覆寫此變數中設定的相同選項. |
優先。 |
由於JDK_JAVA_OPTIONS
環境變數是在 Java 9 中引入的,並且是java
命令獨有的,因此在設定在 Java 9 或更高版本上啟動應用程式的選項時應使用它。但是,如果我們需要在 JDK 工具中全域設定選項,那麼JAVA_TOOL_OPTIONS
是合適的選擇。
6. 結論
在本文中,我們透過實際範例探討了JDK_JAVA_OPTIONS
和JAVA_TOOL_OPTIONS
之間的差異。
我們也了解了何時使用每個變量,幫助我們在不同的 JDK 工具中有效地管理 JVM 選項。