Más contenido relacionado
La actualidad más candente (20)
Similar a より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料) (20)
Más de NTT DATA Technology & Innovation (20)
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
- 1. © 2023 NTT DATA Corporation
より速く より運用しやすく 進化し続けるJVM
Java Developers Summit Online 2023
NTTデータ 阪田 浩一
2023年2月28日
#javasumi23
- 2. © 2023 NTT DATA Corporation 2
自己紹介
• Javaチャンピオン
• Oracle ACE Pro (Java分野)
• 株式会社NTTデータ 所属
• JVMがとにかく好き
• OpenJDKコミッタ
• 💡 2023年2月22日にコミッタになりました!
Koichi Sakata
阪田 浩一
jyukutyo
- 3. © 2023 NTT DATA Corporation 3
このセッションのゴール
参加された方がJVMのここ数年の進化と
今後の方向性について概要をつかめること
注意事項
• 説明のため厳密には正確でない表現をすることがあります
• 聴講者として中級者(JVM GC JITコンパイラの大まかな機能が
わかるくらい)を想定しています
- JVMに詳しい人向けの内容ではありません
- 個々の機能についての技術的詳細は今回の範囲外です
- 5. © 2023 NTT DATA Corporation 5
JVMの進化??
JVMって動作は安定しているし
実行速度が速くなる以外に進化があるの??
より動作が速くなる
• 実行におけるどの部分を速くするのか
- 改善なのかまったく新しい仕組みなのか
より様々なユースケースや環境で実用に耐えられる
よりトラブルに対処しやすくなる
- 6. © 2023 NTT DATA Corporation 6
Javaは速いのか??
観点を変えれば速いとも遅いとも言える
何と比較して速い遅いを決めるか
• 比較すれば遅いが要件に対して十分に速いという場合もある
- 7. © 2023 NTT DATA Corporation 7
クラウド環境でJavaは速いのか??
クラウドで何をするのかにもよる
• IaaSやPaaS上 利用に波がない 今までによくあったタイプ の
Webアプリケーション
• コンテナ利用 利用にスパイクがある Webアプリケーション
• FaaS イベント駆動 アプリケーション
• FaaSだと起動時間の長さ
• コンテナで台数を増やすときに十分なパフォーマンスが
出るまでにかかる時間
が気になる
- 8. © 2023 NTT DATA Corporation 8
観点が異なる時間
起動時間
• JVMが起動するまでの時間
• アプリケーションサーバやサーブレットコンテナが起動するまでの時間
ウォームアップ時間
• 十分なパフォーマンスが出るまでの時間
実行時間
• ある処理を実行して完了させるまでの時間
- 9. © 2023 NTT DATA Corporation 9
観点が異なる時間
起動時間 ウォームアップ時間
javaコマンド実行 アプリケーション起動 良好なパフォーマンス
時間あたりの処理数
実行時間短縮により処理数は増加
古いJava 新しいJava
- 10. © 2023 NTT DATA Corporation 10
起動時間短縮に対する今までの取り組み
これまでも短縮に取り組んできた
• CDS AppCDS ダイナミックCDS
• 多くの細かな改善
JVMをゼロから起動する時間に対する改善の取り組みが多い
• メリットはあるが FaaSだとまだ長い
- 11. © 2023 NTT DATA Corporation 11
起動時間短縮に対する新しい観点での取り組み
JVM起動において起動時間やウォームアップ時間は
一定の時間がかかる
ウォームアップ済みのアプリケーションを保存し
それを再開させる機能があれば
JVMとアプリの起動時間を省けるのでは?
• Project CRaC
JVMを使わず JavaプログラムをC言語のように
実行ファイルにすれば JVMの起動時間や
ウォームアップ時間を省けるのでは?
• GraalVM ネイティブイメージ機能
- 12. © 2023 NTT DATA Corporation 12
起動時間 ウォームアップ時間の短縮
Project CRaC[1]
• Coordinated Restore at Checkpoint
- 起動とウォームアップが完了したJVMとアプリケーションの
イメージを保存する(チェックポイント)
- イメージを復元しればウォームアップ済みのアプリケーションが利用可能となる
(リストア)
- 参考: Linux向けのチェックポイント/リストア機能 CRIU
• OpenJDKのメインラインには未反映
• クラウドベンダの中には先行して独自に取り込みFaaSで使用している
ところもある
[1] https://openjdk.org/projects/crac/ ・ https://github.com/CRaC/docs
- 13. © 2023 NTT DATA Corporation 13
CRaCの利用
-XX:CRaCCheckpointTo=[イメージ保存ディレクトリ]
を付与してアプリケーションを起動する
APIもしくはjcmdでチェックポイントを生成する
• ディレクトリにイメージファイルが出力される
-XX:CRaCRestoreFrom=[上記ディレクトリ]
を付与してjavaコマンドを実行する
アーリーアクセスビルドがある[1]
[1] https://github.com/CRaC/openjdk-builds/releases
- 14. © 2023 NTT DATA Corporation 14
CRaCの注意点
ファイルやソケットはチェックポイント生成前に
アプリケーション側で閉じなければならない
• 閉じずにチェックポイントを生成しようとすると例外が発生する
• 同様にリストアで再びそれらを開く必要がある
CRaCが提供するインタフェースを実装したクラスを
CRaCに登録すればチェックポイント前 リストア後の
タイミングで適切なメソッドを呼び出してくれる
• jdk.crac.Resourceインタフェース
• beforeCheckpoint() afterRestore()メソッド
- 15. © 2023 NTT DATA Corporation 15
CRaCデモ
DBを使っているとコネクションプールにある
コネクションの破棄と生成のコードが必要になる
TomcatやAPサーバも停止と起動が必要になる
今回はCRaCのSpring Bootサンプルアプリ[1]を実行
[1] https://github.com/CRaC/example-spring-boot
- 17. © 2023 NTT DATA Corporation 17
起動時間 ウォームアップ時間の短縮
GraalVM ネイティブイメージ
• Javaバイトコードから実行ファイルを生成する
- 実行ファイルは機械語であり JVMを使わず起動するため速い
- この仕組みからウォームアップという概念はない
• GraalVMは別のプロダクトである
- JDKディストリビューションとはサポートも異なる
- 18. © 2023 NTT DATA Corporation 18
起動時間 ウォームアップ時間の短縮
Project Leyden[1]
• ネイティブイメージ生成と同様のことをOpenJDKで実現する
• 2022年5月 始動
GraalVM CE[2]をOpenJDKに寄贈すると発表があった
• ネイティブイメージ機能も寄贈対象であり Leydenに影響あり
[1] https://openjdk.org/projects/leyden/
[2] GraalVM Community Editionのこと 他にEnterprise Editionがある
- 19. © 2023 NTT DATA Corporation 19
GraalVMとOpenJDKの関係
GraalVMはOpenJDKをベースにして開発したもの
• JITコンパイラを新規に開発
JVM
Compiler Interface
C2
C1
HotSpot VM
C++
GraalVM
Compiler
Interface
GraalVM
JITコンパイラ
C1
HotSpot VM
JVMCI
Java
- 20. © 2023 NTT DATA Corporation 20
GraalVMとOpenJDKの関係
GraalVMはOpenJDKをベースにして開発したもの
• JITコンパイラを新規に開発
• バイトコードを機械語にする仕組みを活用し
アプリ実行中でなくてもバイトコードを機械語にできる機能も開発
- ネイティブコード生成の中核(AOTコンパイル 後述)
JITコンパイラ部分は一時期OpenJDKに含まれていた
• JEP 317: Experimental Java-Based JIT Compiler (Java 10)
• JEP 410: Remove the Experimental AOT and JIT Compiler (Java 17)
- 21. © 2023 NTT DATA Corporation 21
JITコンパイル
JITコンパイラはアプリケーション実行中に
Javaバイトコードを機械語にコンパイル[1]する
Javaバイトコード プロファイル情報
機械語
JITコンパイラによるJITコンパイル
[1] javacでのコンパイルとはまったく別のものです
- 22. © 2023 NTT DATA Corporation 22
GraalVMでのAOTコンパイル
ネイティブイメージ生成ではアプリケーション実行前に
Javaバイトコードを機械語にコンパイルする
Javaバイトコード プロファイル情報
機械語
GraalVMによるAOTコンパイル
- 23. © 2023 NTT DATA Corporation 23
GraalVMの寄贈
JITコンパイラとネイティブイメージ生成機能の一部を寄贈
Project Galahad[1]
• GraalVMの技術をOpenJDKに適用する
• 2022年12月 始動
• 将来的にはGraalVMもこのソースをベースとする予定
ガラハドってアーサー王伝説に出てきた
聖杯を見つけた騎士だよね
Graal(仏) = Holy Grail(英) = 聖杯(日) つながりだ
[1] プロジェクトページはまだないようです
- 24. © 2023 NTT DATA Corporation 24
実行速度向上
Javaのリリースごとに実行パフォーマンスは向上している
• 同じアプリケーションでもより新しいバージョンのJavaを使うだけで
実行速度が向上する
参考となるベンチマーク測定[1]
• Java 8 -> 11 で4%強向上
- https://www.optaplanner.org/blog/2019/01/17/HowMuchFasterIsJava11.html
• Java 11 -> 17 で8%強向上
- https://www.optaplanner.org/blog/2021/09/15/HowMuchFasterIsJava17.html
障害対応も新しいものの方がしやすい
• ランタイムを新しいバージョンにするだけでも恩恵がある
[1] それぞれ別のベンチマークで測定しています この結果が全ユースケースに必ず当てはまるわけではありません
- 25. © 2023 NTT DATA Corporation 25
ガベージコレクタの改善
既存GC(G1 パラレル シリアル)は継続的に改善
• 実行パフォーマンス向上
• メモリ使用量削減
ZGC
• ドラフト版JEP: 世代別ZGC[1]
- アーリーアクセスビルド[2]も出ている
- ZGCが適合する領域が広がる
[1] https://openjdk.org/jeps/8272979
[2] https://jdk.java.net/genzgc/
- 26. © 2023 NTT DATA Corporation 26
メモリ上のオブジェクトヘッダ領域削減
Project Lilliput[1]
• オブジェクトヘッダを96bit(128bit[2])からまず64bitに削減する
- ヒープ使用量削減、GC中の処理量削減、キャッシュの局所性向上
- 結果としてメモリだけでなくCPU使用量も削減できる
• ヘッダーのレイアウトをより柔軟にする
[1] https://wiki.openjdk.org/display/lilliput
[2] Compressed Class Pointersを無効にした場合
- 27. © 2023 NTT DATA Corporation 27
Compressed OopsとCompressed Class Pointers
OopsはJavaヒープ内のオブジェクトへのポインタ
Class Pointersはメタスペース内のクラスメタデータへの
ポインタ
- 29. © 2023 NTT DATA Corporation 29
JVMの進化
速度
• 起動速度
• 実行速度
運用
• プラットフォーム
• ツール
- 30. © 2023 NTT DATA Corporation 30
プラットフォームの追加
8年前にaarch64(Arm)を対応プラットフォームに追加
Java 19でRISC-Vを追加
プラットフォームが増えたからって
何かよいことがあるの??
たとえばクラウド利用時に費用が安い方を選べる
• 同程度の性能でも費用面に違いがある
同程度の性能でもサーバの消費電力量に違いがある
• 電気料金削減だけでなくCO2排出量も削減
- データセンターのゼロエミッション化なども話題に
- 31. © 2023 NTT DATA Corporation 31
ツールの改善
jcmd
JDK Flight Recorder(JFR)
HotSpot Disassembler(HSDIS)
Ideal Graph Visualizer(IGV)
- 32. © 2023 NTT DATA Corporation 32
ツールの統廃合
Java 8: 44個
Java 19: 29個
- 33. © 2023 NTT DATA Corporation 33
jcmd
JVMから情報を取得できる
JVMの設定を変更できる
対象はローカルプロセスのみ
jcmd <pid|main_class> コマンド ...
• pidはプロセスIDのこと
- 34. © 2023 NTT DATA Corporation 34
jcmdの実行例
例1) スレッドダンプ取得
• jcmd <pid> Thread.print
例2) フライトレコード開始
• jcmd <pid> JFR.start duration=1m filename=app.jfr
例3) ログ設定追加
• jcmd <pid> VM.log output="sample.log"
output_options="filecount=3"
- 35. © 2023 NTT DATA Corporation 35
jcmdでのコマンドのドメイン
jcmd <pid> コマンド (コマンドはドメイン.操作という形式)
ドメイン 内容
VM JVMの実行情報取得 ログ設定など
Compiler JITコンパイラ関連
GC ガベージコレクション関連
Thread 現状スレッドダンプのみ
JVMTI JVM Tool Interface関連 エージェントのロードなど
JFR フライトレコード関連
ManagementAgent JMXエージェント関連
※ コマンドとは別個の独立した命令としてPerfcounter.printもある
- 36. © 2023 NTT DATA Corporation 36
VMドメイン
JVM関連の情報取得 設定変更
VM.classloader_stats VM.print_touched_methods
VM.class_hierarchy VM.set_flag
VM.command_line VM.stringtable
VM.dynlibs VM.symboltable
VM.info VM.systemdictionary
VM.log VM.system_properties
VM.flags VM.uptime
VM.native_memory VM.version
- 37. © 2023 NTT DATA Corporation 37
Javaのバージョンとjcmd
バージョンアップとともにコマンドの数が増えている
- 38. © 2023 NTT DATA Corporation 38
jcmd (Java 8)
27個
- 39. © 2023 NTT DATA Corporation 39
jcmd (Java 19)
51個
- 40. © 2023 NTT DATA Corporation 40
使わなくなったコマンド
jcmdで同様のことができるコマンド
jstack
jinfo
• jcmd VMドメインにあるコマンドたちを使用
jmap
• jcmdで以下のようにできる
• 例1) ヒープダンプ: GC.heap_dump <filename>
• 例2) ヒープヒストグラム: GC.class_histogram
- 41. © 2023 NTT DATA Corporation 41
jcmdとJDK Flight Recorder
Project Loomの仮想スレッドに対応
- 42. © 2023 NTT DATA Corporation 42
jfrコマンド
フライトレコードの分析
• JDK Mission Control (JMC)
• jfrコマンド
- 43. © 2023 NTT DATA Corporation 43
jfrコマンド
jfr [サブコマンド] ... jfrファイル
サブコマンド 内容
summary フライトレコードの統計を出力する
print フライトレコードのコンテンツを出力する
assemble 複数のjfrファイルを1つにまとめる
disassemble jfrファイルを複数に分割する
metadata
メタデータとしてイベントそのものに関する情報を
出力する
- 45. © 2023 NTT DATA Corporation 45
HSDIS
ディスアセンブラ 逆アセンブラ
JITコンパイラが生成した機械語をアセンブリ言語に変換する
OpenJDKに含まれるツールの1つ
- 46. © 2023 NTT DATA Corporation 46
HSDIS
機械語は0と1の羅列のため通常読めない
HSDISで機械語をアセンブリ言語に
ディスアセンブルすることで読めるレベルになる
Javaバイトコード
機械語
HSDISでディスアセンブル
アセンブリ言語
- 47. © 2023 NTT DATA Corporation 47
HSDIS
JITコンパイラが生成したコードを確認できる
• 特定のメソッドがコンパイルされているかを確認したい場合がある
- 特定箇所にパフォーマンスに問題があるとき
想定するCPUの命令を使っているかを確認する
• UseAVXなど特別な実行時オプションを指定したなど
- 48. © 2023 NTT DATA Corporation 48
HSDIS
以前はOpenJDKと別の方法でビルドしたが
OpenJDK本体と同じようにビルドできるようになった
ディスアセンブルのバックエンドにGNU Binutilsだけで
なくLLVMとCapstoneも使えるようになった
• LLVM Compiler Infrastructure
• The Ultimate Disassembly Framework – Capstone
- 50. © 2023 NTT DATA Corporation 50
IGV
JITコンパイラの内部動作を可視化するツール
Java製
OpenJDKのリポジトリに含まれる
Mavenでビルドする
- 51. © 2023 NTT DATA Corporation 51
JITコンパイルのプロセス
Java
バイトコード
IR (中間表現) 機械語
最適化を適用し、
IRを変更する
① ③
②
- 52. © 2023 NTT DATA Corporation 52
IR
コードをデータ構造で表現する
• JVMではグラフで表現する
- プログラムの依存をグラフにする
- IRグラフ
- 53. © 2023 NTT DATA Corporation 53
例) x + yをグラフにする
- 54. © 2023 NTT DATA Corporation 54
例) getX() + getY()をグラフにする
- 55. © 2023 NTT DATA Corporation 55
メソッドの呼び出し順序を考慮したグラフ
黄色: 実行順序
緑色: データフロー
- 56. © 2023 NTT DATA Corporation 56
JITコンパイラのアーキテクチャ
フロントエンド バックエンド
- 57. © 2023 NTT DATA Corporation 57
フロントエンド
ハードウェアからは独立
バイトコードからIRを生成する
IRに最適化をほどこす
このIRはHIRと呼ぶ
• High-Level IR: 高水準中間表現
- 58. © 2023 NTT DATA Corporation 58
バックエンド
ハードウェアに依存
レジスタを割り当てる
LIRから機械語を生成する
• Low-Level IR: 低水準中間言語
- 59. © 2023 NTT DATA Corporation 59
JITコンパイラのアーキテクチャ
59
クラス
ロード
バイト
コード HIR
HIR LIR
LIR
機械語
コード
フロントエンド バックエンド
HIR生成
最適化 レジスタ割当
コード生成
- 60. © 2023 NTT DATA Corporation 60
JITコンパイルによる最適化とは
IRグラフに対するパターンマッチ
• グラフのノードを置換する
Aノード Bノード
Cノード
Dノード Dノード
Eノード
最適化パターンにマッチ!
※ 極度に簡略化した例です
- 61. © 2023 NTT DATA Corporation 61
JVMにグラフを出力させる
OpenJDKのデバッグビルド版
• リリース版では以下のオプションは使用できない
-XX:PrintIdealGraphLevel=[0-4]
-XX:PrintIdealGraphFile=filename
出力ファイルをIGVで開く
- 63. © 2023 NTT DATA Corporation 63
まとめ
JVMはJavaのバージョンアップとともに
より速く より運用しやすくなっている
• 実行環境は選び得るもっとも新しいJavaバージョンにしよう
さまざまなプロジェクトが進行中で
細かな改善に加え 新たな観点の機能も加わっていく
- 64. © 2023 NTT DATA Corporation 64
本資料に記載されている会社名、商品名、又はサービス名は、各社の登録商標又は商標です。