Java 仮想マシン (JVM) は、Java プログラムを変更せずに任意のプラットフォームで実行できるようにする Java ランタイム環境 (JRE) のコア コンポーネントです。 JVM は、Java バイトコードと、Java の有名な Write Once Run Anywhere (WORA) 機能を提供する基盤となるハードウェアとの間のインタープリターとして機能します。
- Java ソース (.java) -> javac でコンパイル -> バイトコード (.class)
- JVM はバイトコードをロードし、リンクしていることを確認してから実行します。
- 実行にはバイトコードの解釈や、ジャストインタイム(JIT)コンパイルを使用してホットコードをネイティブマシンコードに変換してパフォーマンスを向上させることが含まれる場合があります。
- ガベージ コレクションはバックグラウンドで実行され、未使用のオブジェクトからメモリを再利用します。
JVMのアーキテクチャ
以下の画像は、JVM のアーキテクチャと主要コンポーネントを示しています。
JVM アーキテクチャのコンポーネント
次に、JVM の各コンポーネントについて詳しく説明します。
1. クラスローダーサブシステム
主に3つの活動を担当します。
1. 読み込み
- .class ファイルを読み取り、クラスのメタデータをメソッド領域に保存します。
- ロードされたクラスを表す Class オブジェクトをヒープ内に作成します。
class GFG{ static{ System.out.println('GFG class is loaded by the JVM!'); } public void display(){ System.out.println('Method of GFG class is executed.'); } } public class Test{ public static void main(String[] args) throws Exception{ System.out.println('Main method started.'); // Loading the class explicitly using Class.forName() Class.forName('GFG'); System.out.println('Class loaded successfully.'); // Creating object to execute method GFG obj = new GFG(); obj.display(); } }
出力
Main method started. GFG class is loaded by the JVM! Class loaded successfully. Method of GFG class is executed.
注記: ロードされたすべての 。クラス ファイルのみ 1つ クラスのオブジェクトが作成されます。
2. リンク: ロードされたクラスの実行準備を担当します。これには次の 3 つのステップが含まれます。
- 検証: バイトコードが JVM ルールに従い、安全に実行できることを確認します。
- 準備: 静的変数にメモリを割り当て、デフォルト値を割り当てます。
- 解決: シンボリック参照をメモリ内の直接参照に変換します。
3. 初期化
- 実際の値を静的変数に割り当てます。
- クラスで定義された静的ブロックを実行します。
クラスローダーのタイプ
- ブートストラップ クラス ローダー: コア Java クラス (JAVA_HOME/lib) をロードします。
- 拡張クラスローダー: 拡張機能ディレクトリ (JAVA_HOME/jre/lib/ext) からクラスをロードします。
- システム/アプリケーション クラス ローダー: アプリケーションのクラスパスからクラスをロードします。
// Java code to demonstrate Class Loader subsystem public class Geeks { public static void main(String[] args) { // String class is loaded by bootstrap loader and // bootstrap loader is not Java object hence null System.out.println(String.class.getClassLoader()); // Test class is loaded by Application loader System.out.println(Geeks.class.getClassLoader()); } }
出力
null jdk.internal.loader.ClassLoaders$AppClassLoader@8bcc55f
2. JVM メモリ領域
- メソッドエリア: クラス名、親クラスのメソッド変数、静的データなどのクラスレベルの情報を保存します。 JVM 全体で共有されます。
- ヒープ領域: すべてのオブジェクトを保存します。 JVM 全体で共有されます。
- スタック領域: 各スレッドには独自のランタイム スタックがあります。メソッドはスタック フレーム内のローカル変数を呼び出します。スレッドが終了すると破棄されます。
- PC レジスタ: 各スレッドの現在実行中の命令のアドレスを保持します。
- ネイティブ メソッド スタック: 各スレッドには、ネイティブ メソッドを実行するための個別のスタックがあります。
3. 実行エンジン
実行エンジンは、.class (バイトコード) を実行します。バイトコードを一行ずつ読み取り、さまざまなメモリ領域に存在するデータと情報を使用して命令を実行します。それは次の 3 つの部分に分類できます。
- 通訳者: バイトコードを 1 行ずつ解釈して実行します。ここでの欠点は、解釈が必要になるたびに 1 つのメソッドが複数回呼び出される場合があることです。
- ジャストインタイムコンパイラ(JIT): 通訳の効率を高めるために使用されます。バイトコード全体をコンパイルしてネイティブ コードに変更するため、インタプリタがメソッド呼び出しの繰り返しを確認するたびに、JIT がその部分に直接ネイティブ コードを提供するため、再解釈が不要になり、効率が向上します。
- ガベージコレクター: 参照されていないオブジェクトは破棄されます。ガベージ コレクターの詳細については、「ガベージ コレクター」を参照してください。 ガベージコレクター 。
4. Java ネイティブ インターフェイス (JNI)
ネイティブメソッドライブラリと連携し、実行に必要なネイティブライブラリ(C C++)を提供するインターフェースです。これにより、JVM は C/C++ ライブラリを呼び出したり、ハードウェアに固有の C/C++ ライブラリによって呼び出されたりできるようになります。
5. ネイティブメソッドライブラリ
これらは、ネイティブ メソッドの実行に必要なネイティブ ライブラリのコレクションです。これらには、C や C++ などの言語で書かれたライブラリが含まれます。