動的コンパイルについて説明します。
C/C++やCOBOLなどで作られたプログラムを実行する場合は、各言語に対応したコンパイラによって、プログラムのソースコードを実行対象プラットフォーム上で動作可能な機械命令へ翻訳(後述の動的コンパイルとの対比で静的コンパイルと呼ばれることがあります)し、事前にプラットフォーム依存の実行バイナリを作成する必要があります。
Javaで作られたプログラムを実行する場合は、javacコマンドによって、プログラムのソースコードをJava VMが解釈/実行できる命令「バイトコード」へ変換し、事前にプラットフォーム非依存の実行バイナリである「クラスファイル」を作成する必要があります。
Javaの実行環境であるJava VMが起動された後、Java VMは、実行対象プログラムであるクラスファイルを読み込み、クラスファイルを以下の2つの方法を用いて実行します。
インタプリタによるバイトコードの実行
Java VMのインタプリタは、クラスファイル内のバイトコードを1命令ずつ解釈して実行します。
機械命令の実行に比べ、実行性能が低速になります。
動的コンパイルにより、バイトコードを機械命令に翻訳してから実行
Javaアプリケーションの実行中、Java VMは、クラスファイル内のJavaメソッドに対応するバイトコードを、実行対象プラットフォーム上で動作可能な機械命令へ自動的に翻訳してから実行します。Javaアプリケーション実行中に自動的に行われる翻訳処理であるため、その翻訳処理を動的コンパイルと呼びます。
インタプリタによるバイトコードの実行に比べ、高速に実行できます。
なお、動的コンパイル処理は、翻訳時における機械命令の最適化処理で必要となる各Javaメソッドの実行頻度や呼び出し関係などの情報を、Javaアプリケーション実行と同時に行われる各Javaメソッドに関するプロファイリング処理の結果から得ます。そのため、プロファイリング処理によりある程度の情報量が得られるまで何度か再翻訳が繰り返され、次第にJavaアプリケーションの実行状況に合った翻訳結果に最適化されることで、機械命令部分の実行性能が向上する傾向があります。
Java VMが行う動的コンパイル自体は、Javaアプリケーションの実行から見ると、オーバーヘッド部分になります。そのため、インタプリタによる実行性能(低速)、動的コンパイルによるオーバーヘッド、および動的コンパイル結果である機械命令による実行性能(高速)の三者をバランス良く調整することで、Javaアプリケーション全体としての実行性能を良くする必要があります。
Java VMは、実行頻度の高いJavaメソッドを優先的にコンパイルし、あまり使われることのないJavaメソッドはインタプリタ実行のままにすることで、インタプリタ実行、動的コンパイル、および動的コンパイル結果である機械命令実行のバランスを取り、Javaアプリケーション全体としての実行性能を良くする調整を行っています。
なお、実行対象となるJavaアプリケーション内で、各Javaメソッドの実行頻度がどの位になるのかについては、実際にJavaアプリケーションが実行されない限り分かりません。そのため、Java VMはJavaアプリケーション実行と同時に各Javaメソッドに関するプロファイリング処理を行い、その結果を用いて動的コンパイルの対象となるJavaメソッドを決定しています。プロファイリング処理によりある程度の情報量が得られるまで、すなわちJava VM起動直後はインタプリタ実行だけですが、次第にインタプリタ実行と動的コンパイル結果による機械命令実行との混合動作になります。
FJVMでは、動的コンパイルに関する以下の機能を富士通版独自機能として実装しています。
以下は、FJVM固有機能です。