Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GraalVM Native Image トラブルシューティング機能の最新状況(2025年版)

GraalVM Native Image トラブルシューティング機能の最新状況(2025年版)

2025年11月15日(土)に開催された JJUG CCC 2025 Fall にて発表した資料です

More Decks by NTTドコモソリューションズ Java担当

Other Decks in Programming

Transcript

  1. © NTT DOCOMO SOLUTIONS, Inc. 2025 1 スピーカー紹介 ◼ NTTドコモソリューションズ株式会社(旧

    NTTコムウェア) ◼ Java/OpenJDK 専門チーム ◼ 担当業務 ◼ Java システムの技術サポートや新技術調査 ◼ JVM トラブルシューティング ◼ OpenJDK 仕様調査(ソースコード解析) ◼ OpenJDK クラッシュ解析 ◼ etc. ◼ JJUG CCC 発表実績 ◼ (2023Fall)GraalVM Native Image 解析方法の紹介 ◼ (2024Fall)Native Memory Tracking を使用した Java プロセスのメモリ消費内訳の紹介 ◼ 本日この後! ◼ (2025Fall)Java プロセスのメモリ監視の落とし穴 ~NMT で見抜けない glibc キャッシュ問題~ 坂本 翔平 (テックリード) 坂本 統 (テックリード)
  2. © NTT DOCOMO SOLUTIONS, Inc. 2025 2 本日のお話 GraalVM Native

    Image のトラブルシューティング機能について、 GraalVM for JDK 21 と 25 の差分に着目して紹介する。 ⚫ GraalVM Native Image に着目し、その解析方法について JJUG CCC 2023 Fall にて紹介 ⚫ 当時は GraalVM for JDK 21 を使用して確認 ⚫ 本日は GraalVM 25 までの Native Image 解析方法に関連するアップデート内容を調査し、 GraalVM for JDK 21 との差分について紹介 ◼ 目次 ◼ GraalVM Native Image について ◼ 調査対象のトラブルシューティング機能 ◼ GraalVM 25 までのアップデートされた機能について ◼ まとめ ◼ 以下の内容はスコープ外 ◼ GraalVM Native Image のビルド方法の詳細 ◼ トラブルシューティング機能に関連しないアップデート内容
  3. © NTT DOCOMO SOLUTIONS, Inc. 2025 3 ◼ Java コードを静的解析して

    AOT(事前)コンパイルし、 単独実行可能なバイナリファイルを生成する機能 ◼ Native Image 機能で生成したアプリケーションは 以下のメリットを持つ ◼ JDK 不要で高速起動 ◼ 低メモリフットプリント ◼ 即ピークパフォーマンス ◼ 生成されたアプリケーションは、 HotSpot VM ではなく軽量な Substrate VM を使用 ⇒ 従来の JVM 関連情報の取得方法などに差異がある App(バイナリファイル) GraalVM Native Image について Native Image は GraalVM の主要機能の1つであり、 AOT コンパイルにより自己完結型の実行ファイルを生成する。 ◼ 次世代の Java 開発・実行環境 ◼ OpenJDK ベースで開発 ◼ 代表的な機能は以下の3つ ◼ Graal JIT コンパイラ ◼ 多言語実行環境(Truffle) ◼ Native Image ◼ 2025/9に GraalVM 25 がリリース GraalVM とは GraalVM Native Image とは OS Java VM(HotSpot VM) App.class OS Substrate VM App Code 通常の Java App の実行環境 Native Image で生成した App の実行環境
  4. © NTT DOCOMO SOLUTIONS, Inc. 2025 4 調査対象のトラブルシューティング機能 情報種別 取得方法

    HotSpot VM Native Image(GraalVM for JDK 21) バージョン情報 $ java -version $ strings <native_image> | grep “com.oracle.svm.core.VM” オプション情報 $ ps aux | grep java $ ps aux | grep <native_image> GC ログ -Xlog:gc -XX:+PrintGC -XX:+VerboseGC など スレッドダンプ $ jcmd <pid> Thread.print (ビルド時)-H:+DumpThreadStacksOnSignal $ kill -QUIT <pid> ヒープダンプ $ jcmd <pid> GC.heap_dump <output> -XX:+HeapDumpOnOutOfMemoryError (ビルド時)--enable-monitoring=heapdump $ kill -USR1 <pid> フライトレコード -XX:StartFlightRecording=… $ jcmd <pid> JFR.start (ビルド時)--enable-monitoring=jfr -XX:StartFlightRecording=… Native Memory Tracking(NMT) $ jcmd <pid> VM.native_memory 取得不可 エラーレポート HotSpot VM による出力 Substrate VM による出力 コアダンプ OS 機能による出力 / sudo gcore <pid> (ビルド時) -g OS 機能による出力 / sudo gcore <pid> トラブルシューティングに必要な情報を取得できる機能を調査対象とする。 2023年当時に調査した結果
  5. © NTT DOCOMO SOLUTIONS, Inc. 2025 5 動作確認環境 動作確認は Linux

    環境で実施。詳細は以下の通り。 ◼ (補足)GraalVM Native Image によるビルドについて ◼ Spring PetClinic はデフォルトでネイティブビルドをサポート済 ◼ (Maven 利用の場合)以下コマンドの実行でネイティブビルド可能 項目 種類やバージョンなど 備考 マシン環境 OS: Ubuntu 22.04 LTS CPU: 4コア8スレッド メモリ: 16GB Java アプリケーション Spring PetClinic ※Commit b26f235 ※ を利用 ・Spring Boot 3.5.6 ・Native Build Tools 0.10.6 Java 実行環境 GraalVM 25+37.1 $ ./mvnw -Pnative native:compile ... $ ls ./target/ ... spring-petclinic ※ https://github.com/spring-projects/spring-petclinic/commit/b26f235250627a235a2974a22f2317dbef27338d
  6. © NTT DOCOMO SOLUTIONS, Inc. 2025 6 GraalVM 25 までのアップデートに伴う差分

    項目(赤字: 21から差分あり) GraalVM 22-25 のアップデート 備考 バージョン情報 ①jcmd サポートの追加 オプション情報 ①jcmd サポートの追加 動作確認では取得不可 GC ログ 差分なし スレッドダンプ ①jcmd サポートの追加 ②スレッドダンプの取得サポートの追加と -H:+DumpThreadStacksOnSignal の非推奨化 ②は GraalVM for JDK 22 で --enable- monitoring=threadump がサポートされたことによりオ プションが非推奨となった ①のサポート前は kill -QUIT による取得のみ可能 ヒープダンプ ①jcmd サポートの追加 フライトレコード ①jcmd サポートの追加 ③新規 JFR イベントのサポート追加 Native Memory Tracking(NMT) ①jcmd サポートの追加 ④NMT の初期サポートの追加 エラーレポート 差分なし コアダンプ 差分なし 調査対象に関連する GraalVM 25 までのアップデートは以下の通り。 ①jcmd サポートの追加(GraalVM for JDK 24) ②スレッドダンプの機能サポート追加と従来のオプションの非推奨化 ③新規 JFR イベントのサポート追加(GraalVM for JDK 22-23) ④NMT の初期サポートの追加(GraalVM for JDK 23)
  7. © NTT DOCOMO SOLUTIONS, Inc. 2025 7 jcmd サポート(1/2) GraalVM

    for JDK 24 で追加され、各種情報取得が容易となった。 Native Image のビルドオプションを指定 --enable-monitoring=jcmd を指定することで、jcmd 機能を有効化できる。 $ native-image –-enable-monitoring=jcmd <java_app_name> jcmd によるコマンド実行 実行中のアプリケーションプロセスに対して jcmd コマンドを実行できる。実行例※ は以下の通り ・バージョン情報 ・ヒープダンプ $ jcmd <pid> VM.version XXXXXX: GraalVM CE 25+37.1 (serial gc) JDK 25+37 $ jcmd <pid> GC.heap_dump heapdump.hprof XXXXXX: Dumped to: heapdump.hprof ※スレッドダンプ、フライトレコード、Native Memory Tracking も取得可能だが詳細は別ページで説明 jcmd は GraalVM 同梱のバイナリを使用
  8. © NTT DOCOMO SOLUTIONS, Inc. 2025 8 jcmd サポート(2/2) 実行可能な診断コマンドは、指定したビルドオプションにより変わる点に注意。

    実行可能な診断コマンドの変化 ビルドオプション --enable-monitoring= で指定した文字列で実行可能な診断コマンドが変化※ する。 実行可能な jcmd の診断コマンドは jcmd <pid> help で出力できる。 (例) --enable-monitoring=jcmd のみ なお --enable-monitoring=all を指定することで全ての診断コマンドが利用できる。 $ jcmd <pid> help XXXXXX: The following commands are available: GC.run Thread.dump_to_file Thread.print VM.command_line VM.system_properties VM.uptime VM.version help ※Supported Diagnostic Commands: https://www.graalvm.org/latest/reference-manual/native-image/debugging-and-diagnostics/jcmd/#supported-diagnostic-commands
  9. © NTT DOCOMO SOLUTIONS, Inc. 2025 9 スレッドダンプ(1/2) スレッドダンプ取得機能が GraalVM

    for JDK 22 でサポートされるようになり、 -H:±DumpThreadStacksOnSignal は非推奨となった。 Native Image のビルドオプションを指定 --enable-monitoring=threaddump を指定することでスレッドダンプ取得機能を有効化できる。 $ native-image –-enable-monitoring=threaddump <java_app_name> QUIT シグナル送信によるスレッドダンプ取得 実行中のアプリケーションプロセスに対して QUIT シグナルを送信すればスレッドダンプを出力できる。 ※ GraalVM for JDK 21 までは -H:±DumpThreadStacksOnSignal により機能を有効化できたが、 --enable-monitoring のサポート追加により非推奨となった。 このオプションを引き続き使用しているとビルド時に以下の警告が出力される。 $ kill –QUIT <pid> Warning: Option 'DumpThreadStacksOnSignal' is deprecated and might be removed in a future release: Please use '--enable-monitoring=threaddump'. Please refer to the GraalVM release notes. 出力はアプリケーションプロセス側に標準エラー出力される
  10. © NTT DOCOMO SOLUTIONS, Inc. 2025 10 スレッドダンプ(2/2) スレッドダンプは前述の jcmd

    サポート追加に伴い、 jcmd コマンドで取得することもできる。 jcmd コマンドによるスレッドダンプの取得 実行中のアプリケーションプロセスに対して、jcmd <pid> Thread.print を実行することで スレッドダンプを取得できる。 jcmd コマンドでスレッドダンプを操作する場合、ビルド時に jcmd を有効化する必要があるため注意。 なお前述の --enable-monitoring=threaddump は QUIT シグナルによるスレッドダンプ出力のための 機能であり、診断コマンド Thread.print についてはこのビルドオプションの指定がなくても使用可能。 また jcmd によるスレッドダンプもアプリケーションプロセス側で標準エラー出力される点は注意。 $ jcmd <pid> Thread.print XXXXXX: Threads dumped.
  11. © NTT DOCOMO SOLUTIONS, Inc. 2025 11 フライトレコード(1/2) jcmd サポート追加に伴い、jcmd

    コマンドで JDK Flight Recorder が 操作できるようになった。 Native Image のビルドオプションを指定 --enable-monitoring=jfr,jcmd を指定することで、jcmd による JFR 操作を有効化する。 jfr のみの指定だと Java 起動オプションによる JFR 制御はできるが、jcmd による操作はできない。 $ native-image –-enable-monitoring=jfr,jcmd <java_app_name> jcmd コマンドによるフライトレコードの操作 実行中のアプリケーションプロセスに対して jcmd コマンドで JFR を操作できる。 診断コマンドは JFR.start / JFR.stop / JFR.dump / JFR.check の4種が使用できる。 なお HotSpot VM で使用できた JFR.view および JFR.configure については未実装である。 $ jcmd <pid> JFR.start XXXXXX: Started recording 1. No limit specified, using maxsize=250MB as default.
  12. © NTT DOCOMO SOLUTIONS, Inc. 2025 12 フライトレコード(2/2) いくつかの新規 JFR

    イベントのサポートが追加された。 JFR イベント 追加されたバージョン 説明 備考 jdk.AllocationRequiringGC GraalVM for JDK 22 GC を必要とする割当情報 jdk.SystemGC System.gc() の情報 jdk.ThreadAllocationStatistics スレッド割当統計 jdk.ObjectAllocationSample GraalVM for JDK 23 オブジェクトの割当のサンプリング情報 jdk.OldObjectSample Old 領域の生存オブジェクトのサンプリング情報 jdk.NativeMemoryUsage カテゴリごとのメモリ使用量 jdk.NativeMemoryUsageTotal Total のメモリ使用量 jdk.NativeMemoryUsagePeak カテゴリごとのメモリ使用量のピーク Native Image 固有イベント jdk.NativeMemoryUsageTotalPeak Total のメモリ使用量のピーク Native Image 固有イベント 未実装の JFR イベントについては Graal VM の Issue #5410 ※で実装検討中。 ※ https://github.com/oracle/graal/issues/5410
  13. © NTT DOCOMO SOLUTIONS, Inc. 2025 13 Native Memory Tracking(1/2)

    GraalVM for JDK 23 で初期サポートが追加された。 Native Image のビルドオプションを指定 --enable-monitoring=nmt を指定することで、NMT 機能を有効化できる。 $ native-image –-enable-monitoring=nmt <java_app_name> NMT 情報の取得方法 NMT 機能を有効化することで –XX:+PrintNMTStatistics が利用できる。 これはアプリケーションの終了時に NMT 情報を出力する。 またビルド時に jcmd サポートを有効化することで jcmd を用いた NMT 情報の取得が可能となる。 jcmd で取得するには診断コマンド VM.native_memory を使用する。 $ ./myapp –XX:+PrintNMTStatistics $ jcmd <pid> VM.native_memory XXXXXX: Native memory tracking …
  14. © NTT DOCOMO SOLUTIONS, Inc. 2025 14 Native Memory Tracking(2/2)

    jcmd コマンドで summary 情報を能動的に取得できるようになった。 $ jcmd XXXXXX VM.native_memory XXXXXX: Native memory tracking Total (reserved=33554456KB, committed=138139KB) (malloc=24KB, count=28) (peak malloc=2448KB, count at peak=33) (mmap: reserved=33554432KB, committed=138114KB) (mmap: peak reserved=33554432KB, peak committed=149378KB) Compiler (reserved=0KB, committed=0KB) (malloc=0KB, count=0) (peak malloc=0KB, count at peak=0) (mmap: reserved=0KB, committed=0KB) (mmap: peak reserved=0KB, peak committed=0KB) Code (reserved=0KB, committed=0KB) … 各項目について、 reserved / committed、malloc および mmap の メモリ量を出力するのは HotSpot VM と同様 Native Image における NMT 情報では summary 情報相当のみ出力可能。 detail 相当の情報や、baseline との diff 情報の取得はできない点に注意。
  15. © NTT DOCOMO SOLUTIONS, Inc. 2025 15 その他 jcmd サポートが追加されたが、

    動作確認ではオプション情報は取得できなかった。 ◼ オプション情報 ◼ (参考)HotSpot VM の出力例 $ ps aux | grep myapp User 955644 4.8 1.3 35319040 189748 pts/3 Sl+ 11:33 0:00 ./myapp -Xmx100m - Xms100m -XX:+PrintGC $ jcmd 955644 VM.command_line 955644: VM Arguments: java_command: オプション情報が出力されない $ jcmd 125737 VM.command_line 125737: VM Arguments: jvm_args: -Xmx100m -Xms100m -Xlog:gc java_command: myapp …
  16. © NTT DOCOMO SOLUTIONS, Inc. 2025 16 まとめ GraalVM 25

    における Native Image の解析情報の取得方法について以下にまとめる。 情報種別 取得方法 必要なビルドオプション 起動オプションや取得コマンド バージョン情報 --enable-monitoring=jcmd $ jcmd <pid> VM.version オプション情報 - $ ps aux | grep <native_image> GC ログ - -XX:+PrintGC, -XX:+VerboseGC など スレッドダンプ --enable-monitoring=jcmd $ jcmd <pid> Thread.print --enable-monitoring=threaddump $ kill -QUIT <pid> ヒープダンプ --enable-monitoring=heapdump -XX:+HeapDumpOnOutOfMemoryError $ kill –USR1 <pid> --enable-monitoring=jcmd,heapdump $ jcmd <pid> GC.heap_dump <output> フライトレコード --enable-monitoring=jfr -XX:StartFlightRecording=… --enable-monitoring=jcmd,jfr $ jcmd <pid> JFR.start/stop/dump/check Native Memory Tracking(NMT) --enable-monitoring=nmt -XX:+PrintNMTStatistics --enable-monitoring=jcmd,nmt $ jcmd <pid> VM.native_memory エラーレポート - Substrate VM による出力 コアダンプ -g(デバッグ情報の生成のため) OS機能による出力 / sudo gcore <pid> アップデートあり
  17. © NTT DOCOMO SOLUTIONS, Inc. 2025 19 (参考)GraalVM バージョン間の差分 GraalVM

    for JDK 21 と GraalVM 25 の情報取得の差分は以下の通り。 情報種別 取得方法 GraalVM for JDK 21 GraalVM 25 バージョン情報 $ strings <native_image> | grep “com.oracle.svm.core.VM” $ jcmd <pid> VM.version オプション情報 $ ps aux | grep <native_image> GC ログ -XX:+PrintGC -XX:+VerboseGC など スレッドダンプ (ビルド時)-H:+DumpThreadStacksOnSignal $ kill -QUIT <pid> $ jcmd <pid> Thread.print (ビルド時)--enable-monitoring=threaddump $ kill -QUIT <pid> ヒープダンプ -XX:+HeapDumpOnOutOfMemoryError (ビルド時)--enable-monitoring=heapdump $ kill -USR1 <pid> 左に加えて $ jcmd <pid> GC.heap_dump <output> フライトレコード (ビルド時)--enable-monitoring=jfr -XX:StartFlightRecording=… 左に加えて $ jcmd <pid> JFR.start/stop/dump/check Native Memory Tracking(NMT) 取得不可 (ビルド時)--enable-monitoring=nmt -XX:+PrintNMTStatistics $ jcmd <pid> VM.native_memory エラーレポート Substrate VM による出力 コアダンプ (ビルド時) -g(デバッグ情報生成のため) / sudo gcore <pid> など 差分あり
  18. © NTT DOCOMO SOLUTIONS, Inc. 2025 20 (参考)未実装の JFR イベント例

    VisualVM で可視化可能な項目のうち未実装なものは以下の通り。 JFR イベント VisualVM メニュー 情報の説明 備考 jdk.ThreadDump Overview – Thread dump スレッドダンプ jdk.CPULoad Monitor - CPU usage/Environment - CPU utilization CPU 使用量 jdk.MetaspaceSummary Monitor – Metaspace usage Metaspace 使用量 jdk.FileRead jdk.FileWrite File IO ファイル I/O jdk.SocketRead jdk.SocketWrite Socket IO ソケット I/O jdk.JavaErrorThrow jdk.JavaExceptionThrow Exceptions エラーおよび例外一覧 jdk.GCConfiguration jdk.GCHeapConfiguration jdk.YoungGenerationConfiguration jdk.GCSurvivorConfiguration jdk.GCTLABConfiguration GC – GC configuration GC – Heap configuration GC – Young Generation configuration GC – Survivor configuration GC – TLAB configuration 各種 GC 関連の設定値 jdk.ObjectCount Sampler - Heap histogram 各オブジェクトの数 #7402 ※1 で検討中 jdk.ThreadAllocationStatistics Sampler - Per Thread Allocation スレッド割当統計 #7263 ※2 でマージ済 jdk.CPUInformation Environment - CPU details CPU 情報 jdk.NetworkUtilization Environment - Network utilization ネットワーク使用量 jdk.SystemProcess Environment - System processes ホストで実行中のプロセス一覧 ※1 https://github.com/oracle/graal/issues/7402 ※2 https://github.com/oracle/graal/pull/7263
  19. © NTT DOCOMO SOLUTIONS, Inc. 2025 21 (参考)NMT 情報の出力項目の差異 HotSpot

    VM と Native Image の Substrate VM では、 NMT 情報の出力項目に差異がある。 以下は動作確認の出力結果を基に項目の差異を確認した結果である。 ◼ HotSpot VM と Substrate VM の共通項目 ◼ Total, Java Heap, Thread, Code, GC, Compiler, Internal, Native Memory Tracking, Serviceability ◼ HosSpot VM のみ出力される項目 ◼ Class, Symbol, Shared class space, Arena Chunk, Module, Safepoint, Synchronization, Metaspace, String Deduplication, Object Monitors ◼ Substrate VM のみ出力される項目 ◼ Heap Dump, Image Heap, JFR, JNI, jvmstat, JVMTI, PGO, Unsafe