實作細節
Espresso 的運作方式與其他使用 Truffle 實作的語言一樣,可以作為原生可執行檔或在 HotSpot 上執行(目前僅適用於 Linux)。在第一種情況下,當 Espresso 執行階段編譯為原生可執行檔時,它不需要 HotSpot 來執行 Java。但是,它需要標準的核心 Java 程式庫(Java 8 的 *rt.jar* 程式庫或 Java 11+ 的 *lib/modules file*,以及相關的原生程式庫:libjava
、libnio
等)。
Espresso 是一個精簡的 Java VM,實作了 VM 的所有核心組件,包括
- 位元組碼解譯器
- 位元組碼驗證器
- 單一 Java 類別檔案剖析器
- 簡單的物件模型
- Java 原生介面 (JNI) 在 Java 中的實作
- Java 中的虛擬機器實作
- Java 除錯線路協定 (JDWP)
Espresso 重用了 GraalVM 中的所有 JAR 檔案和原生程式庫。所有原生程式庫和方法都會透過 Truffle 原生函式介面 (JNI) 載入/存取/呼叫。JNI 控制代碼是在 Espresso 中實作的,例如,所有 Truffle NFI 方法只會接收和傳回基本型別。為了獲得效能,某些方法會被替換,例如,Math.sqrt
、System.arraycopy
,以避免昂貴的轉換為原生。
如果從多個 Espresso 環境或甚至同時從在 HotSpot 上執行的 Espresso 和 Java 使用某些原生程式庫,則這些原生程式庫可能包含會衝突的靜態資料。在 Linux 上,Espresso 使用 Truffle NFI 的功能,嘗試在隔離的命名空間中載入程式庫 (dlmopen
)。這僅適用於具有 glibc
的 Linux,並且有很多限制。當在原生可執行檔中執行時,不會使用此模式,因為不會與 HotSpot 衝突。
目前限制 #
- Espresso 不會實作 JVM 工具介面 (JVMTI)。因此,它不支援
-agentlib
或-agentpath
VM 選項。 - Espresso 不會實作
java.lang.instrument
介面。因此,它不支援-javaagent
VM 選項。 - Espresso 目前使用 Java 核心程式庫中的標準原生程式庫。這需要允許多語言
Context
原生存取。由於這些程式庫的載入方式(透過 Truffle NFI),在 HotSpot 上執行僅適用於 Linux (具有glibc
)。作為原生可執行檔的一部分執行適用於 Linux、Windows 和 macOS,但目前僅限於一個環境。 - 對 Java 管理擴充功能 (JMX) 的支援是部分的,而且某些方法可能會傳回部分資料。
- 與 HotSpot 相比,除錯器協定實作 (JDWP) 缺少某些功能。它會正確報告支援的功能。特別是不支援需要列舉所有 Java 物件的動作。但是,它確實支援 HotSpot 不支援的一些熱重新載入案例。
- 當
java.MultiThreaded
選項設定為「false」時,不會發生參考處理。根據應用程式的不同,這可能會造成資源外洩。請注意,如果 Espresso 在啟用單執行緒語言(例如,JavaScript)的環境中執行,則此選項會自動設定為「false」。 - Espresso 尚不支援多語言 API。但是,它提供了客座 Java 多語言 API,在
polyglot.jar
中說明。如需更多資訊,請參閱與 Truffle 語言的互通性。