- JDK 23 向け GraalVM (最新)
- JDK 24 向け GraalVM (早期アクセス)
- JDK 21 向け GraalVM
- JDK 17 向け GraalVM
- アーカイブ
- 開発ビルド
Graal コンパイラ
Graal コンパイラは、Java で記述された、バイトコードをマシンコードに変換する動的コンパイラです。Graal ジャストインタイム (JIT) コンパイラは、Java HotSpot Virtual Machine および GraalVM と統合されています。詳細については、Java Virtual Machine Guide および「仮想マシンとしての GraalVM」のセクションを参照してください。(Graal JIT コンパイラのオープンソースコードはGitHubで入手できます。)
コンパイラの利点 #
Graal JIT コンパイラは、コード分析と最適化に対する独自のアプローチを通じて、Java Virtual Machine (JVM) 上で実行されるアプリケーションに最適化されたパフォーマンスを提供します。アグレッシブインライン化、ポリモーフィックインライン化など、複数の最適化アルゴリズム (「フェーズ」と呼ばれる) が含まれています。
Graal コンパイラは、高度に抽象化されたプログラムに対してパフォーマンス上の利点をもたらすことができます。たとえば、特定のオブジェクトのコストのかかる割り当てを削除できる部分エスケープ分析最適化が含まれています。詳細については、GraalVM GitHub リポジトリのCEOptimization enum
のPartialEscapeAnalysis
の値を参照してください。この最適化では、新しいオブジェクトがコンパイルユニットの外部でアクセス可能になる場合を判断し、コンパイルユニットを「エスケープ」するパスでのみオブジェクトを割り当てます (たとえば、オブジェクトがパラメータとして渡されたり、フィールドに格納されたり、メソッドから返されたりする場合)。このアプローチにより、ヒープ割り当ての数を減らすことで、アプリケーションのパフォーマンスを大幅に向上させることができます。Streams や Lambdas などのよりモダンな Java 機能を使用するコードでは、このタイプのコードは多数の非エスケープまたは部分エスケープオブジェクトを伴うため、パフォーマンスが大幅に向上します。コンパイラで削除できない I/O やメモリ割り当てなどの特性に拘束されたコードでは、改善は少なくなります。パフォーマンスチューニングの詳細については、「Graal JIT コンパイラの設定」を参照してください。
グラフコンパイル #
ホスト JVM ベースの言語と同じランタイムでゲストプログラミング言語 (具体的には JavaScript、Python、Ruby) を実行するために、コンパイラはソース言語と生成されるマシンコード間の言語に依存しない中間グラフ表現を使用します。(言語間の相互運用性の詳細については、「相互運用性」を参照してください。)
グラフは、異なる言語の同様のステートメント (「if」ステートメントやループなど) を同じ方法で表現できるため、同じアプリケーションで言語を混在させることが可能です。Graal コンパイラは、言語に依存しない最適化を実行し、このグラフ上にマシンコードを生成できます。
診断データ #
コンパイラによってキャッチされない例外がスローされた場合、通常、コンパイルは破棄され、実行が継続されます。Graal コンパイラは、代わりに、バグレポートと一緒に送信できる診断データ (即時表現グラフなど) を生成できます。これは、-Djdk.graal.CompilationFailureAction=Diagnose
オプションで有効になります。診断出力のデフォルトの場所は、プロセスの現在の作業ディレクトリにあるgraal_dumps/ディレクトリですが、-Djdk.graal.DumpPath
オプションで変更できます。JVM のシャットダウン中に、診断データを含むアーカイブの場所がコンソールに出力されます。
さらに、-Djdk.graal.Dump
オプションを使用すると、Graal コンパイラによって実行されたすべてのコンパイルに対して診断データを生成できます。これにより、コンパイラによってコンパイルされたすべてのメソッドの診断データが生成されます。
診断データが生成されるメソッドのセットを絞り込むには、-Djdk.graal.MethodFilter=<クラス>.<メソッド>
オプションを使用します。たとえば、-Djdk.graal.MethodFilter=java.lang.String.*,HashMap.get
は、java.lang.String
クラスのメソッドと、非修飾名が HashMap
であるクラスの get
という名前のメソッドに対してのみ診断データを生成します。