在标准 JDK 上运行 GraalJS

GraalJS 针对作为 GraalVM 部分执行进行了优化,主要建议在 Java 应用程序中使用。这通过使用 Graal 编译器 作为优化编译器,以及可能使用 原生镜像 将引擎提前编译成原生二进制文件,来保证最佳性能。

但是,也可以在标准 Java VM(例如 Oracle JDK 或 OpenJDK)上执行 GraalJS。在没有 Graal 编译器的情况下执行时,JavaScript 性能将显着下降。虽然标准 JVM 上可用的 JIT 编译器可以执行和 JIT 编译 GraalJS 代码库,但它无法将 GraalJS 优化到其最佳性能潜力。本文档介绍了如何在标准 Java VM 上运行 GraalJS,并展示了如何将 Graal 编译器用作 JIT 编译器以保证最佳性能。

Maven Central 上的 GraalJS #

GraalJS 是开源的,并由社区定期推送到 Maven Central Repository。您可以在 org.graalvm.polyglot:js 中找到它。

我们提供在 JDK 21(或更高版本)上运行 GraalJS 嵌入 Java 并使用 Graal 编译器的示例项目

  • 多语言嵌入演示。用于简单的 JavaScript “Hello World” 应用程序的 Maven 和 Gradle 项目。
  • JS Maven 演示。此示例包含用于 JavaScript 基准测试(素数生成器)的 Maven 项目。它允许用户比较 GraalJS 使用或不使用 Graal 编译器作为优化编译器运行时的性能。使用 Graal 编译器运行会显着提高任何相对较大的 JavaScript 代码库的执行性能。实质上,示例 pom.xml 文件激活了 JVM 编译器接口 (JVMCI) 并通过在 --module-path--upgrade-module-path 上提供它来将 JIT 编译器配置为 Graal 编译器。

ScriptEngine JSR 223 #

js-scriptengine.jar 包含在模块路径上时,GraalJS 可以通过 ScriptEngine 启动。引擎在几个不同的名称下注册,包括 Graal.jsjsJavaScriptjavascript。请注意,如果模块路径上存在 Nashorn 引擎,它也可能在其名称下可用。

要从 ScriptEngine 启动 GraalJS,可以使用以下代码

new ScriptEngineManager().getEngineByName("Graal.js");

列出所有可用引擎

List<ScriptEngineFactory> engines = new ScriptEngineManager().getEngineFactories();
for (ScriptEngineFactory f : engines) {
    System.out.println(f.getLanguageName() + " " + f.getEngineName() + " " + f.getNames());
}

检查设置 - GraalVM 编译器是否用作 JIT 编译器? #

--engine.TraceCompilation 选项在每次 JavaScript 方法由 Graal 编译器编译时启用调试输出。运行时间足够长的 JavaScript 源代码将触发编译并打印日志输出

> function add(a,b) { return a+b; }; for (var i=0;i<1000*1000;i++) { add(i,i); }
[truffle] opt done         add <opt> <split-c0875dd>                                   |ASTSize       7/    7 |Time    99(  90+9   )ms |DirectCallNodes I    0/D    0 |GraalNodes    22/   71 |CodeSize          274 |CodeAddress 0x7f76e4c1fe10 |Source    <shell>:1:1

与我们联系