Welcome, GraalVM for JDK 22!

原文はこちら。
The original article was written by Alina Yurenko (Developer Advocate for GraalVM, Oracle Labs).
https://medium.com/graalvm/welcome-graalvm-for-jdk-22-8a48849f054c

本日GraalVM for JDK 22をリリースしました。

Download Oracle GraalVM
https://www.graalvm.org/downloads/

いつものように、Oracle JDKとOpenJDKのリリース同日にGraalVMをリリースします。Java 22機能のサポートに関しては、そのほとんどがGraal JITとNative Imageで利用可能で、今後のリリースに向けて積極的に取り組んでいます。ご期待ください。

Availability of Java 22 features on GraalVM

すでにGraalVMをダウンロードできる状態になっておりますので、詳細についてはリリースノートを確認してください。

GraalVM for JDK 22 Release Notes
https://www.graalvm.org/release-notes/JDK_22/

このリリースの新機能を知りたい方は、このブログ記事を読み進めてください。また、ライブ・ストリームの録画は以下からどうぞ。

Parsing 1 Billion Rows in Java in 0.3 Seconds 🔥

Javaの世界の人なら、1BRC について聞いたことがあるかもしれません。Gunnar Morling氏(@gunnarmorling)による課題で、最新のJavaを使って10億行を含むファイルをいかに速く処理できるかというものです。

1️⃣🐝🏎️ The One Billion Row Challenge — A fun exploration of how quickly 1B rows from a text file can be aggregated with Java
https://github.com/gunnarmorling/1brc

2ヶ月間、Javaパフォーマンス・コミュニティ全体がこのチャレンジに注目していたようです(私たちもそうでした!)。このチャレンジから学ぶことはたくさんありますが、それは後ほど紹介するとして、まずは結果を見てみましょう。Gunnarが提案したベースライン・ソリューションでは、ファイルの処理に04分49秒かかりました。その後、出場者はさまざまなパフォーマンス最適化を適用し、8コアで01.53秒、32コアで0.3秒という驚異的な時間まで短縮しました!

The 1BRC challenge results (top-5)

最速ソリューションの大半がGraalVM、特にNative Imageを使用していることがわかります。QuestDBのMarko Topolnik氏の言葉を引用してみます。

コードに触れる前に、低労力で可能なプログラム高速化の方法があります。それは、最新のJVMを使うことです。

1BRCチャレンジで、GraalVMが非常に高速なJVMであることを理解しました。

The Billion Row Challenge (1BRC) – Step-by-step from 71s to 1.7s
https://questdb.io/blog/billion-row-challenge-step-by-step

以下はコミュニティからのフィードバックです。

興味深いのは、Native Imageが処理を高速に行うだけでなく、そのために使用するCPUリソースも少ないということです。Thomas WuerthingerのソリューションをJVMとNative Imageで計測したところ、JVMでは1行の処理に約125CPUサイクルを要したのに対し、Native Imageでは(PGOなしでも)78CPUサイクルしかかかりませんでした。Native ImageはJavaアプリケーションをより高速で環境に優しいものにします!🌿

並列化、SIMD、分岐なしコードなど、参加者が使用した具体的な最適化技術については、InfoQの記事を読むか、Nicolai Parlogのライブストリーム録画をご覧ください。

The One Billion Row Challenge Shows That Java Can Process a One Billion Rows File in Two Seconds
https://www.infoq.com/news/2024/01/1brc-fast-java-processing/
「One Billion Row Challenge」でJavaが10億行のファイルを2秒で処理できることを実証
https://www.infoq.com/jp/news/2024/02/1brc-fast-java-processing/

その他の関連するアップデートでは、JavaのrecordのequalsメソッドとhashCodeメソッドで、Intrinsicsのメソッドハンドルを使用するようになりました。これにより、Native Imageのrecordのパフォーマンスが大幅に向上します。

New Class Initialization Strategy

GraalVM for JDK 21の--strict-image-heapinで導入された新しいクラス初期化アプローチが、デフォルトになりました。すべてのクラスは、クラスの初期化設定に関係なく、ビルド時に使用、初期化ができるようになりました。--initialize-at-run-timeとして設定されているけれども、ビルド時にも使用されるクラスについては、これは、それらが実行時に再び未初期化として表示されることを意味します。主要なフレームワークはすでにこの新しい戦略を採用しており、ほとんどのユーザーにとってスムーズな移行が期待できます。

詳細はGitHub PRをご覧ください。

[GR-39406] Add new class initialization strategy that allows all classes to be used at image build time. #4684
https://github.com/oracle/graal/pull/4684

Better Native Image Profiling with Flame Graphs 🔥

ネイティブイメージビルドレポートは、生成されたバイナリファイルとビルドプロセス自体に関する様々なデータを表示できます。

Inspecting a Profile in a Build Report
https://www.graalvm.org/jdk22/reference-manual/native-image/optimizations-and-performance/PGO/build-reports/

特に、ビルドレポートはプロファイリング情報をフレームグラフとして可視化できるようになりました。これは、インスツルメンテーションの実行中に収集されたプロファイルに基づいて、異なるメソッドが実行時間全体にどのように寄与しているかを調べるのに便利です。

グラフ付きのビルド・レポートを生成するには、PGO最適化ネイティブ実行ファイルをビルドするステップで-H:+BuildReport-H:+BuildReportSamplerFlamegraphオプションを渡します(その際、--pgoとプロファイル・ファイルの名前も含めるようにしてください)。

Profiling flamegraph

詳細は以下のドキュメントをご覧ください。

Inspecting a Profile in a Build Report
https://www.graalvm.org/jdk22/reference-manual/native-image/optimizations-and-performance/PGO/build-reports/

New PGO features

プロファイルガイド付き最適化は、Native Imageのパフォーマンスを向上させるために必要不可欠ですが、良いプロファイルを集めるのは必ずしも簡単ではありません。この体験をシンプルにするために、生成されたプロファイルの品質を評価するのに役立つ新しい実験的ビルドオプションを導入しました。Native Imageのビルド時に-H:+PGOPrintProfileQualityを渡すと、ビルド出力でステップ 5 – インライン化メソッド – の新たな行を見ることになるでしょう。

GraalVM Native Image: Generating 'demo-app' (executable)...
...
[5/8] Inlining methods...     [***]                                                                      (0.4s @ 0.28GB)
Info: PGO: Profile applicability is 21.67%. Profile relevance is 72.66%.                                                                  (6.8s @ 0.29GB)
...

Profile applicability(プロファイルの有効性)は、プロファイルがソースコード内の要求された場所に関するデータを含む頻度を示す指標です。Profile relevance(プロファイルの関連性)は、(プロファイルはコードの変更を導入する前に取得された可能性があるため)プロファイルがアプリケーションで見られるメソッドとどの程度一致しているかを示します。プロファイルの有用性は、ビルド間でプロファイルを再利用する場合や、アプリケーションの同じビルドに対して異なるプロファイルを提供する場合に、メトリックの変化を観察することから得られます。

優れたプロファイルのもう1つの重要な品質はcompleteness(完全性)です。これは、インスツルメンテーションされたアプリを関連するワークロードで十分な時間実行し、できるだけ多くの関連するコードパスを実行することで達成されます。これを達成するには、複数のインスツルメンテッド実行が必要な場合がありますが、その場合、複数のプロファイルをマージできます。

Merging Profiles from Multiple Sources
https://www.graalvm.org/jdk22/reference-manual/native-image/optimizations-and-performance/PGO/merging-profiles/

また、PGOのドキュメントを拡張しました。深く掘り下げるためにリファレンスマニュアルをチェックするか、入門やガイドであれば、最近のブログエントリをご覧ください。

Profile Guided Optimizations for Native Image
https://medium.com/graalvm/profile-guided-optimization-for-native-image-f015f853f9a8
https://logico-jp.io/2024/03/14/profile-guided-optimizations-for-native-image/

Native Image meets Project Panama 🚀

Foreign Function & Memory API(JEP 454、Project Panamaの一部)の実験的サポートを追加しました。

JEP 454: Foreign Function & Memory API
https://openjdk.org/jeps/454

この API は -H:+ForeignAPISupport(と-H:+UnlockExperimentalVMOptions)を付けて明示的に有効にする必要があります。現在のところ、x64アーキテクチャでの外部メモリ機能と外部関数のダウンコールのサポートが含まれていますが、FFM APIの完全なサポートに向けて積極的に取り組んでいます。制限付きネイティブ操作(restricted native operation)を実行するモジュールは、--enable-native-accessオプションを使用して指定する必要があります。FFM APIサポートのより詳細な概要については、以下をご覧ください。

Foreign Function and Memory API in Native Image
https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/ForeignInterface.md
https://www.graalvm.org/latest/reference-manual/native-image/native-code-interoperability/foreign-interface/

Oracle GraalVM Buildpack 📦

Oracle GraalVMのための別の統合を追加したことにより、あなたのプロジェクト、特にSpring Bootのプロジェクトに統合するのが簡単になりました。例として、以下をspring-boot-maven-pluginの設定セクションに追加します。

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
    <image>
      <!-- ... -->
      <buildpacks>
        <buildpack>docker.io/paketobuildpacks/oracle</buildpack>
        <buildpack>urn:cnb:builder:paketo-buildpacks/java-native-image</buildpack>
      </buildpacks>
    </image>
  </configuration>
</plugin>

Gradleの場合の手順や詳細については以下のブログエントリをご覧ください。

Oracle GraalVM Now Available as a Paketo Buildpack
https://medium.com/graalvm/oracle-graalvm-now-available-as-a-paketo-buildpack-7b6a7dbb939c
https://logico-jp.io/2023/12/13/oracle-graalvm-now-available-as-a-paketo-buildpack/

Native Image Developer Experience

Native Imageでのリフレクションの使用がより簡単になりました。Java Objectクラス、プリミティブクラス、配列クラスのメソッド、フィールド、コンストラクタがデフォルトでリフレクションに登録されるようになりました。

NATIVE_IMAGE_OPTIONS環境変数のサポートが追加され、ユーザーやツールが環境経由で追加の引数を渡すことができるようになりました。JAVA_TOOL_OPTIONSと同様に、この環境変数の値はnative-imageに供給されるオプションの前に付けられます。例えば、ローカルでのGraalVM Native Imageの全てのビルドでクイック・ビルド・モードをオンにする場合は以下のように使うと実現できます。

# for Bash
echo 'export NATIVE_IMAGE_OPTIONS="${NATIVE_IMAGE_OPTIONS} -Ob"' >> "${HOME}/.bashrc"

# for Zsh
echo 'export NATIVE_IMAGE_OPTIONS="${NATIVE_IMAGE_OPTIONS} -Ob"' >> "${HOME}/.zshrc"

Native Imageでメタデータが欠落している場合の報告方法を改善しました。このような場合は特別な例外を投げるようになりました(実験的な扱いです)。-H:ThrowMissingRegistrationErrors=<package-prefix> オプションを使用することで、メタデータの例外を早期に検出し、関連する問題をデバッグできます(全パッケージの場合は -H:ThrowMissingRegistrationErrorsを付けてください)。

以下の JFR イベントのサポートを追加しました。これはRed Hat社との共同開発です。

  • AllocationRequiringGC
  • SystemGC
  • ThreadAllocationStatistics

Native Imageでは、スレッドダンプを作成するための API オプション --enable-monitoring=threaddump を利用できるようになりました。-H:±DumpThreadStacksOnSignal オプションは非推奨となり、削除される予定です。

Native Imageエージェント呼び出しの追跡の仕組みを改良しました。ClassLoader.findSystemClassObjectInputStream.resolveClass、およびBundles.ofの呼び出しをエージェントが追跡し、リソースバンドルをバンドル名とロケールのペアとして登録するようになりました。

また、GraalVM で小さなコンテナイメージを構築するのに役立つステップバイステップのデモを公開しました。

Tiny Java Containers
https://github.com/graalvm/graalvm-demos/tree/master/tiny-java-containers

Compiler Updates 🚀

Project Galahadに向けた取り組みとして、Graal JITコンパイラのオプションにはjdk.graal.という接頭辞を使用するようになりました(例えば、-Djdk.graal.PrintCompilation=true)。従来のgraal.接頭辞は非推奨ですが、まだ使用できます(例えば、-Dgraal.PrintCompilation=true)。

Project Galahad
https://openjdk.org/projects/galahad/

毎回のリリースと同様に、パフォーマンスの改善に取り組んできました。コミュニティからのフィードバックやパフォーマンス報告を受け取るのは素晴らしいことです。今回は、Ionut Balosin氏(@ionutbalosin)とFlorin Blanaru氏(@gigiblender)による素晴らしいパフォーマンス研究を目にしました。彼らは、JDK 21で利用可能な様々なJITコンパイラのパフォーマンスを幅広いベンチマークセットで比較していました。彼らの測定によると、Graal JITを使用することで、アプリケーションはarm64で17%、x64で23%高速化しました。

JVM Performance Comparison for JDK 21
ionutbalosin.com/2024/02/jvm-performance-comparison-for-jdk-21/

Native Build Tools 🛠️

Native Build Tools (NBT) は、デフォルトでGraalVMの到達可能性メタデータ・リポジトリへのアクセスを可能になっています。これは、NBTを使用するプロジェクト(およびNBTに依存するフレームワーク)のために、既知のライブラリのための設定が自動的に解決されることを意味します。ライブラリの使用がより簡単になりました!🚀

Repository which contains community-driven collection of GraalVM reachability metadata for open-source libraries.
https://github.com/oracle/graalvm-reachability-metadata

また、最近のNBTリリースでいくつかの変更と改善を行いました。まだの方は0.10.1にアップグレードしてください。

Release 0.10.1
https://github.com/graalvm/native-build-tools/releases/tag/0.10.1

Community and Ecosystem

Oracle NetSuiteは、パフォーマンスを改善し、リソースの消費を削減するために、GraalVM JDKに完全に移行しました。

GraalVM at Oracle NetSuite
https://medium.com/graalvm/graalvm-at-oracle-netsuite-47501f3461a4

GitHubの2000以上のリポジトリで、GraalVM GitHubアクションが使われています。

Dependency graph
https://github.com/graalvm/setup-graalvm/network/dependents

最新のGraalVMビルド上で動作するJHipster Liteプロジェクト・ジェネレーターは、1秒で起動し、140MBのRAMしか使用しないため、0.25vCPU.5GBのRAMのクラウドインスタンスで本番稼動が可能です!

JHipster Lite
https://lite.jhipster.tech/landscape

Marcus Hellberg氏は、Spring AIとVaadinを使ってAIチャットボットを素早く簡単に構築する方法を共有しました。GraalVMで0.1秒で起動します。

JavaアプリケーションにLLM機能をもたらすライブラリLangchain4jは、GraalVM Native Imageで動作します!QuarkusとSpring Bootのガイドを参照してください。

LangChain4J: Java version of LangChain
https://github.com/langchain4j/langchain4j
When Quarkus meets LangChain4j
https://quarkus.io/blog/quarkus-meets-langchain4j/
LangChain4J example (Spring Boot)
https://github.com/langchain4j/langchain4j-examples/blob/main/spring-boot-example/src/test/java/dev/example/CustomerSupportApplicationTest.java

TornadoVMを使ってGPUを活用することで、Polyglot GraalVMアプリケーションをさらに高速化できます。

Hardware Acceleration for Polyglot Runtimes
https://www.tornadovm.org/post/hardware-acceleration-for-polyglot-runtimes

JavaScriptのようなGraalVM言語をデータベース内で実行できるOracle DatabaseのGraalVM埋め込み機能であるMLE (Multilingual Engine) についてはご存知かもしれません。JavaScript実行のための同様のモジュールがMySQLでも利用できるようになりました。

Introducing JavaScript support in MySQL
https://blogs.oracle.com/mysql/post/introducing-javascript-support-in-mysql

GraalVMを使用することで、Cloud Run上で動作するJavaアプリケーションを10倍速く、3倍小さくする方法をご覧ください。

Cloud Run: The Spring Boot rebirth with GraalVM native compilation
https://medium.com/google-cloud/cloud-run-the-spring-boot-rebirth-with-graalvm-native-compilation-bacd14307cb0

最初からNative-Image対応で開発されるライブラリがますます増えています。例としてnative TypeMapをチェックしてください。

Conclusion

この場を借りて、このリリースに寄せられたフィードバック、提案、貢献に対する素晴らしい貢献者とコミュニティに感謝したいと思います。

このリリースに対するフィードバックや、今後のリリースに欲しい機能の提案がありましたら、Slack、GitHub、Twitterで共有してください。

Slack invitation
https://www.graalvm.org/slack-invitation
GitHub Issues
https://github.com/oracle/graal
Twitter
https://twitter.com/graalvm

それでは、新しい GraalVM をお試しください!🚀

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください