原文はこちら。
The original article was written by Alina Yurenko (Developer Advocate for GraalVM, Oracle Labs).
https://medium.com/graalvm/graalvm-22-2-smaller-jdk-size-improved-memory-usage-better-library-support-and-more-cb34b5b68ec0
本日、GraalVM 22.2をリリースします。このリリースは、新機能と開発者エクスペリエンスに多くの改善をもたらします。
このリリースにはJDK 11とJDK 17のサポートが含まれています。いつものように、GitHubからGraalVM Communityをダウンロードするか、OTNからGraalVM Enterpriseビルドを入手できます。また、VS CodeのGraalVM Extension Pack for Javaや、macOSのHomebrewでも最新版のGraalVMのインストールができます。それでは、このリリースの新機能を見てみましょう。
GraalVM Community Edition 22.2.0
https://github.com/graalvm/graalvm-ce-builds/releases
Oracle GraalVM Downloads
https://www.oracle.com/downloads/graalvm-downloads.html
GraalVM Extension Pack for Java
https://marketplace.visualstudio.com/items?itemName=oracle-labs-graalvm.graalvm-pack
Homebrew Tap for GraalVM
https://github.com/graalvm/homebrew-tap
または、リリースストリームのリプレイをご覧ください。
Smaller GraalVM JDK distribution
ランタイムの重要な側面の一つは、その基本ディストリビューションのサイズです:ランタイムのサイズは、ダウンロード時間や開発者の経験に影響を与えます。22.2以降、ベースのGraalVM JDKはモジュール化が進み、JavaScriptランタイム、LLVMランタイム、VisualVMを含まなくなりました。これらのコンポーネントをインストールするには、すでにNative Image、Python、Ruby、または他のGraalVMコンポーネントをインストールしたのと同じ方法で、gu install js
、gu install llvm
、またはgu install visualvm
を使用します。これはつまり、ベースとなるGraalVM JDKのダウンロードサイズがより小さくなるということです。JVM上でJavaアプリケーションを実行するためにGraalVMを使用しているか、またはNative Imageを使用している場合、JDKダウンロードが大幅に小さくなることを除いて、GraalVMをセットアップしてアプリケーションを実行する方法に変更はありません。下表は、JDK17アーティファクトの22.1と22.2を比較したものです。

この変更により、CI/CDのセットアップがより効率的になり、GraalVMユーザーの開発者エクスペリエンスが向上することを願っています。
Making third-party libraries support Native Image
Native Imageはアプリケーションのメインエントリーポイントから到達可能なコードのみをビルドプロセスでコンパイルします。このアプローチにより、最高の起動性能とリソースの使用量が最適化されますが、リフレクションやシリアライゼーションなどの動的なJava機能に対する課題を引き起こします。アプリケーションのある要素が到達可能でない場合、その要素はネイティブ実行ファイルに含まれません。しかし、その要素が必要で、実行時にリフレクションによってアクセスされる場合に、失敗につながる可能性があります。Native Imageが到達不可能と判断した要素を含めるには、Native Imageにメタデータ(設定情報)を提供する必要があります。メタデータは、フレームワークが自動的に提供するか、またはトレースエージェントを使い手動で作成します。
Assisted Configuration with Tracing Agent
https://www.graalvm.org/22.0/reference-manual/native-image/Agent/
このタスクをさらに簡素化するために、我々はraalVM Reachability Metadata Repository(GraalVM到達性メタデータリポジトリ)を導入しました。これはライブラリとフレームワークのメンテナ(およびNative Imageユーザ)がNative Imageのメタデータを共有するために使用可能な一元化されたリポジトリです。
GraalVM Reachability Metadata Repository
https://github.com/oracle/graalvm-reachability-metadata
メタデータの使用とコントリビューションについての詳細は、以下のエントリをご覧ください。
Enhancing 3rd-Party Library Support in GraalVM Native Image with Shared Metadata
https://medium.com/graalvm/enhancing-3rd-party-library-support-in-graalvm-native-image-with-shared-metadata-9eeae1651da4
このメタデータリポジトリは、GraalVM Native Build Toolsと統合されています。
Native Build Tools
https://github.com/graalvm/native-build-tools
例えば、Gradleプロジェクトでメタデータリポジトリの自動使用を有効にするには、build.gradle
の設定に以下を追加します。
graalvmNative {
metadataRepository {
enabled = true
}
}
メタデータリポジトリは、プロダクションのNative Image アプリケーションにおけるサードパーティライブラリの使用を大幅に簡素化するものです。みなさまからのコントリビューションをお待ちしています。
Smaller memory footprint of Native Image builds
内部データ構造の改良により、ネイティブ実行ファイルをビルドする際にNative Imageツールが必要とするメモリが大幅に削減されました。このメモリ使用量の削減は、クラウドサービスやGitHub Actionsなど、メモリに制約のある環境では特に有益です。リリース22.2以降、Native Imageツールは2GBのJavaヒープだけで多くの大きなネイティブ実行ファイルを正常にビルドできるようになりました。
例えば、Spring PetClinicアプリケーションは2GBのメモリでビルドできるようになっています。
======================================================================================================================== | |
GraalVM Native Image: Generating 'petclinic-jpa' (executable)... | |
======================================================================================================================== | |
[1/7] Initializing... (12.2s @ 0.47GB) | |
Version info: 'GraalVM 22.2.0 Java 17 EE' | |
Java version info: '17.0.4+11-LTS-jvmci-22.2-b05' | |
C compiler: gcc (linux, x86_64, 9.4.0) | |
Garbage collector: Serial GC | |
[2/7] Performing analysis... [*********] (67.5s @ 1.92GB) | |
26,184 (94.56%) of 27,689 classes reachable | |
42,026 (68.44%) of 61,409 fields reachable | |
140,935 (67.78%) of 207,928 methods reachable | |
1,397 classes, 415 fields, and 7,894 methods registered for reflection | |
65 classes, 74 fields, and 55 methods registered for JNI access | |
4 native libraries: dl, pthread, rt, z | |
[3/7] Building universe... (56.5s @ 1.95GB) | |
[4/7] Parsing methods... [***] (5.9s @ 1.48GB) | |
[5/7] Inlining methods... [****] (2.4s @ 1.55GB) | |
[6/7] Compiling methods... [****] (19.4s @ 1.74GB) | |
[7/7] Creating image... (8.4s @ 1.68GB) | |
43.28MB (45.39%) for code area: 97,635 compilation units | |
47.41MB (49.73%) for image heap: 579,002 objects and 835 resources | |
4.65MB ( 4.87%) for other data | |
95.34MB in total | |
------------------------------------------------------------------------------------------------------------------------ | |
Top 10 packages in code area: Top 10 object types in image heap: | |
3.21MB com.oracle.svm.core.code 9.99MB byte[] for code metadata | |
1.20MB jdk.proxy4 9.00MB byte[] for embedded resources | |
1.06MB sun.security.ssl 5.83MB byte[] for java.lang.String | |
878.77KB java.util 4.73MB java.lang.Class | |
814.08KB com.mysql.cj.jdbc 4.22MB java.lang.String | |
555.53KB org.hibernate.hql.internal.antlr 3.53MB byte[] for general heap data | |
488.76KB org.apache.coyote.http2 1.65MB byte[] for reflection metadata | |
476.47KB org.apache.catalina.core 1.20MB com.oracle.svm.core.hub.DynamicHubCompanion | |
465.88KB java.lang.invoke 725.72KB c.o.svm.core.hub.DynamicHub$ReflectionMetadata | |
460.78KB com.sun.crypto.provider 599.67KB java.lang.String[] | |
33.08MB for 1101 more packages 5.06MB for 4765 more object types | |
------------------------------------------------------------------------------------------------------------------------ | |
77.2s (42.7% of total time) in 306 GCs | Peak RSS: 3.42GB | CPU load: 9.52 | |
------------------------------------------------------------------------------------------------------------------------ | |
Produced artifacts: | |
/home/janedoe/demos/spring-native/samples/petclinic-jpa/target/petclinic-jpa (executable) | |
/home/janedoe/demos/spring-native/samples/petclinic-jpa/target/petclinic-jpa.build_artifacts.txt (txt) | |
======================================================================================================================== | |
Finished generating 'petclinic-jpa' in 3m 0s. |
Generating heap dumps in Native Image
ネイティブ実行ファイルのヒープを実行時にダンプする機能が、GraalVM Communityでサポートされるようになりました。-XX:+DumpHeapAndExit
という、ネイティブ実行ファイルの初期ヒープをダンプする新しいコマンドラインオプションを含め、ヒープをダンプする方法にはいくつかあります。
Create a Heap Dump from a Native Executable
https://www.graalvm.org/22.2/reference-manual/native-image/guides/create-heap-dump/
ヒープダンプは、VisualVMのようなJavaヒープダンプツールで解析できます。

Native Imageのその他のアップデートには以下のようなものがあります。
- GraalVM EnterpriseのNative ImageにSoftware Bill of Materials (SBOM) のサポートが追加されました。SBOMは、ソフトウェアアーティファクトで使用されるコンポーネントのリストです。GraalVM Native Imageは、脆弱性スキャナーを支援するために、オプションでSBOMをネイティブ実行ファイルに含めることができるようになりました。現在、CycloneDX形式をサポートしており、コンパイル時に、コマンドラインオプション
-H:IncludeSBOM=cyclonedx
を使用すると有効化できます。圧縮されたSBOMを実行ファイルに埋め込んだ後、ネイティブイメージインスペクションツール(GraalVM Enterpriseで利用可)を使用して、以下のコマンドで圧縮されたSBOMを抽出できます。
$GRAALVM_HOME/bin/native-image-inspect - sbom <path_to_binary>
Native Image Inspection Tool
https://www.graalvm.org/22.1/reference-manual/native-image/inspect/
- Linuxでのデバッグのサポートが改善されました。Dwarf 情報にパラメータとローカル変数が含まれるようになりました。Red Hatからのコントリビューションに感謝します!また、IntelliJ IDEA 2022.2 EAP 5の Native Imageのデバッグに関する新しい実験的なサポートをチェックしてください。 これについては、近日中にさらなる更新を予定しています。
Experimental GraalVM Native Debugger for Java (IntelliJ IDEA 2022.2 EAP 5: Support for Spring 6 and Spring Boot 3 Features, Enhanced HTTP Client, Kubernetes Updates and More)
https://blog.jetbrains.com/idea/2022/06/intellij-idea-2022-2-eap-5/#Experimental_GraalVM_Native_Debugger_for_Java
Compiler updates
Reduced memory usage in JIT mode
【JITモードでのメモリ使用量削減】
Graalコンパイラは、実行時にメモリをより効率的に使用するようになりました。アプリケーションがウォームアップし、コンパイルがほとんど必要ない安定した状態になると、Graalコンパイラは未使用のメモリーをシステムに解放します。次のコマンドを実行して、自分のワークロードでメモリへの影響を評価してください。
$ps aux --sort --rss
New strip mining optimization for counted loops
【加算ループのための新しいストリップマイニングの最適化】
ストリップマイニングは、長時間実行される単一のループを、内部本体が制限時間だけ実行されるネストされたループに変換します。これにより、外側のループにセーフポイントを配置でき、セーフポイントポーリングのオーバーヘッドを削減できます。外側のループのストライドを適切に選択することで、セーフポイントのレイテンシを適切に確保できます。後者は、ZGCやShenandoahのような低休止時間のガベージコレクタで特に重要です。以下の例をご覧ください。
for (long i = init; i < limit; i += stride) {
use(i);
}
上記のコードは以下のように最適化されます。
final long stripMax = (long) CountedStripMiningInnerLoopTrips;
for (long i = init; i < limit;) {
long innerTrips = i < limit - stripMax ? stripMax : limit - i;
long i_ = i;
for (long j = 0; j |<| innerTrips; j++) {
use(i_);
i_ += stride;
}
i = i_;
}
その結果、外部メモリアクセスAPIを使用するコードなど、longレンジのチェックを行うワークロードで約20%の速度向上が確認されています。この最適化は、Truffle 言語にも有効です。22.2ではこの最適化は実験的なものであり、コマンドラインオプション
-Dgraal.StripMineCountedLoops=true
で有効にする必要があります。この最適化は22.3ではデフォルトで有効化される予定です。
global value numbering for fixed nodes early in the compilation pipeline
【コンパイル・パイプライン初期における、固定ノードに対するグローバルな値のナンバリング】
もう1つの新しい最適化は、コンパイル・パイプラインの初期に固定ノードに対するグローバルな値のナンバリングです。この最適化により、複雑な部分エスケープ解析とループ展開(Loop unrolling)による最適化を必要とするワークロードを改善し、(例えば、一部の Ruby ワークロードに見られる)複雑なオブジェクト割り当てを伴う定数ループを最適化します。ビルド時間を短縮し (コンパイルパイプラインの早い段階でグラフサイズを小さくする)、メモリ操作をより多く折り畳むことで生成されるネイティブ実行ファイル自体を高速化できるため、この最適化はNative Imageにも非常に有効である可能性があります。このリリースでは、この最適化はデフォルトで無効になっています。以下のコマンドラインオプションで試してみてください。
-Dgraal.EarlyGVN=true
GraalVM Enterprise for Apple Silicon and new components for GraalVM Community
Apple SiliconのユーザーがGraalVM Enterpriseを使ってアプリケーションを開発できるようになりました!ビルドは以下から入手できます。
Oracle GraalVM Downloads
https://www.oracle.com/downloads/graalvm-downloads.html
Apple SiliconのサポートはGraalVMのGitHubで最もリクエストの多かった機能の一つで、今回GraalVM Enterpriseのユーザーもその恩恵を受けることができるようになりました。
Support for Apple M1 (darwin-aarch64) #2666
https://github.com/oracle/graal/issues/2666
このリリースでは、サポートは実験的なものであることに注意してください。問題報告やフィードバックをお願いします。
JDKとNative Imageに加え、GraalVM CommunityとEnterprise Editionの両方で、多くのコンポーネントに対するApple Siliconのサポートを追加しました。
- JavaScript
- the LLVM toolchainおよびランタイム
- Ruby
- Java on Truffle
- Webassembly
GraalPython: faster startup and extended library support
GraalPythonに実験的なバイトコードインタプリタを追加し、起動の高速化とインタプリタの性能の向上を図りました。このリリースでは、デフォルトでは有効になっていないため、以下のコマンドラインオプションを使って有効化してください。
--python.EnableBytecodeInterpreter
さらに、HPy バージョン 0.0.4 に更新しました。これは、Kiwi の HPy への移植(完了)と、Matplotlib と NumPy の移植(現在進行中)をサポートします。
Improved interoperability in GraalJS
22.2 から、他の言語からのオブジェクトは、デフォルトで適切なJavaScriptのプロトタイプが割り当てられるようになりました。この機能は、以前は実験的なものでしたが、配列、関数、および他の型としてforeignオブジェクトをJavaScriptから見せることによって、コードの移植性を向上させるものです。詳細は追ってブログ記事でお知らせします。
Community Contributions
このリリースに協力してくれたコミュニティとエコシステムのパートナーにいつもながら感謝しています。GitHub には多くの有益な報告やコントリビューションをいただきました。そして、フィードバックを共有し、GraalVM のプラットフォームで他のコミュニティメンバーを助けることで、私たちは共同で皆のために GraalVM をより良くしていくことができます。
GraalVM Community
https://www.graalvm.org/community/
とりわけ以下のコントリビューションに感謝しております。
- Linuxでのデバッグサポートの改善(Red Hat)
- メタデータリポジトリの構築(Oracle、Quarkus、Spring Bootチームの共同作業)
Conclusion
GraalVMコミュニティの皆様に対し、本リリースへのフィードバック、ご提案、ご協力に感謝申し上げます。このリリースに関する追加のフィードバックや、将来のリリースに追加して欲しい機能に関する提案があれば、Slack、GitHub、Twitterで共有してください。
Slack invitation
https://www.graalvm.org/slack-invitation
GitHub Issues
https://github.com/oracle/graal
Twitter
https://twitter.com/graalvm