logo

JVM の仕組み - JVM アーキテクチャ

Java 仮想マシン (JVM) は、Java プログラムを変更せずに任意のプラットフォームで実行できるようにする Java ランタイム環境 (JRE) のコア コンポーネントです。 JVM は、Java バイトコードと、Java の有名な Write Once Run Anywhere (WORA) 機能を提供する基盤となるハードウェアとの間のインタープリターとして機能します。

  • Java ソース (.java) -> javac でコンパイル -> バイトコード (.class)
  • JVM はバイトコードをロードし、リンクしていることを確認してから実行します。
  • 実行にはバイトコードの解釈や、ジャストインタイム(JIT)コンパイルを使用してホットコードをネイティブマシンコードに変換してパフォーマンスを向上させることが含まれる場合があります。
  • ガベージ コレクションはバックグラウンドで実行され、未使用のオブジェクトからメモリを再利用します。

JVMのアーキテクチャ

以下の画像は、JVM のアーキテクチャと主要コンポーネントを示しています。

ジェヴム' title=

JVM アーキテクチャのコンポーネント

次に、JVM の各コンポーネントについて詳しく説明します。



1. クラスローダーサブシステム

主に3つの活動を担当します。 

クラスローダーサブシステム' loading='lazy' title=

1. 読み込み

  • .class ファイルを読み取り、クラスのメタデータをメソッド領域に保存します。
  • ロードされたクラスを表す Class オブジェクトをヒープ内に作成します。
Java
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
// 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++ などの言語で書かれたライブラリが含まれます。