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

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

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 オブジェクトをヒープ内に作成します。
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++ などの言語で書かれたライブラリが含まれます。


クイズの作成