版本
- 适用于 JDK 24 的 GraalVM(最新)
- 适用于 JDK 25 的 GraalVM(早期访问)
- 适用于 JDK 21 的 GraalVM
- 适用于 JDK 17 的 GraalVM
- 存档
- 开发构建
实现细节
Espresso 与其他通过 Truffle 实现的语言一样,既可以作为原生可执行文件运行,也可以在 HotSpot 上运行(目前仅支持 Linux)。在前一种情况下,当 Espresso 运行时被编译为原生可执行文件时,它无需 HotSpot 即可运行 Java。但是,它需要一个标准的 Java 核心库(Java 8 的 rt.jar 库或 Java 11+ 的 lib/modules 文件),以及相关的原生库:libjava
、libnio
等。
Espresso 是一个精简的 Java 虚拟机,它实现了虚拟机的所有核心组件,包括:
- 字节码解释器
- 字节码验证器
- 单一 Java 类文件解析器
- 简单对象模型
- Java 中实现的 Java 本机接口 (JNI)
- Java 中实现的虚拟机
- Java 调试线协议 (JDWP)
Espresso 复用 GraalVM 中的所有 JAR 文件和原生库。所有原生库和方法都通过 Truffle 本机函数接口 (JNI) 加载/访问/调用。JNI 句柄在 Espresso 中实现,例如,所有 Truffle NFI 方法只接收和返回基本类型。为了提高性能,某些方法被替换,例如 Math.sqrt
、System.arraycopy
,以避免昂贵的原生代码转换。
某些原生库可能包含静态数据,如果从多个 Espresso 上下文使用,或者同时从 Espresso 和在 HotSpot 上运行的 Java 使用,可能会发生冲突。在 Linux 上,Espresso 利用 Truffle NFI 的能力尝试在独立的命名空间 (dlmopen
) 中加载库。此功能仅在带有 glibc
的 Linux 上可用,并且存在许多限制。当作为原生可执行文件运行时,不会使用此模式,因为不会与 HotSpot 发生冲突。
当前限制 #
- Espresso 未实现 JVM 工具接口 (JVMTI)。因此,它不支持
-agentlib
或-agentpath
虚拟机选项。 - Espresso 未实现
java.lang.instrument
接口。因此,它不支持-javaagent
虚拟机选项。 - Espresso 当前使用 Java 核心库中的标准原生库。这需要允许多语言
Context
进行原生访问。由于这些库的加载方式(通过 Truffle NFI),在 HotSpot 上运行仅适用于 Linux(带有glibc
)。作为原生可执行文件的一部分运行时,它可在 Linux、Windows 和 macOS 上运行,但目前仅限于一个上下文。 - 对 Java 管理扩展 (JMX) 的支持是部分的,某些方法可能返回不完整的数据。
- 与 HotSpot 相比,调试器协议实现 (JDWP) 缺少一些功能。它将正确报告支持的功能。特别是,不支持需要枚举所有 Java 对象的行为。但是,它确实支持一些 HotSpot 不支持的热重载情况。
- 当
java.MultiThreaded
选项设置为“false”时,将不会发生引用处理。根据应用程序的不同,这可能会导致资源泄漏。请注意,如果 Espresso 在启用了单线程语言的上下文(例如 JavaScript)中运行,此选项将自动设置为“false”。 - Espresso 尚不支持 Polyglot API。但是,它提供了一个客户端 Java Polyglot API,在
polyglot.jar
中有所描述。有关更多信息,请参阅与 Truffle 语言的互操作性。