JVMの基礎知識(1)

1. 全体的なアーキテクチャとコンポーネント

        1.クラスローダー

        クラス ローダー (クラス ローダー) は、.class ファイルを JVM にロードし、対応する Java クラス オブジェクト (クラス オブジェクト) を生成する役割を果たします。Java には 3 つのクラス ローダーがあります。

  • Bootstram ClassLoader: C++ で実装され、JVM の一部であるコア クラス ライブラリをロードします。
  • Extension ClassLoader: Java で実装された Java 拡張クラス ライブラリ (javax.* パッケージなど) をロードし、sun.misc.Launcher の一部です。
  • App ClassLoader: Java で実装されたアプリケーション クラスのロードは、ClassLoader のサブクラスです。

        .2.実行エンジン

        実行エンジンは、バイトコードを解釈し、それを機械語命令に変換し、プログラムを実行します。JVM の実行エンジンには 2 つのモードが含まれています。

  • 解釈モード: バイトコードを 1 行ずつ解釈し、対応する機械命令を実行します。このモードの利点は、すぐに開始できることですが、実行速度は遅くなります。
  • コンパイラ モード: バイトコードをローカル マシン命令にコンパイルし、コンパイルされたコードを実行します。このモードの利点は、実行速度は速いですが、起動速度が遅いことです。

        JVM は、プログラムの実行中に必要に応じてインタプリタ モードとコンパイラ モードを動的に選択する混合モード (Mixed Mode) を採用しています。

        3.ランタイムデータ領域

ランタイム データ領域 (ランタイム データ領域) は、JVM 内のデータ ストレージ領域であり、次のコンポーネントが含まれます。

  • メソッド領域: クラス情報、定数、静的変数、その他のデータを格納します。
  • ヒープ (ヒープ): Java オブジェクトと配列を格納します。
  • スタック(stack): Javaメソッドのローカル変数、オペランドスタック、メソッド出口などの情報を格納します。
  • PC レジスタ (プログラム カウンタ): 実行中の Java メソッドのアドレスを格納します。
  • ネイティブ メソッド スタック: Java がネイティブ メソッドを呼び出すためのサポートを提供します。

        4.ネイティブメソッドインターフェース

        ネイティブ メソッド インターフェイス (ローカル メソッド インターフェイス) を使用すると、Java コードから C または C++ で記述されたネイティブ メソッドを呼び出すことができます。ネイティブ メソッドは、JNI (Java Native Interface) を通じて実装されます。JVM は Java パラメータを C/C++ パラメータに変換し、ネイティブ メソッドを呼び出して結果を返します。

        JVM の全体的なアーキテクチャとコンポーネントは、Java プログラムを実行するための基礎です。Java プログラマにとって、JVM の原理と内部メカニズムを理解することは、より効率的で安定した Java プログラムを作成するのに役立ちます。

2. コンポーネント間の相互作用

        2.1クラスローダーとメソッド領域

Java クラスが初めてロードされるとき、クラス ローダーはクラスの .class ファイルをメモリに読み取り、クラスのメンバー変数とメソッドを含む対応する Class オブジェクトをメソッド領域に作成します。JVM の実行中、クラスのバイトコード、ランタイム定数プール、フィールドおよびメソッドの情報など、すべてのクラス情報がメソッド領域に保存されます。

        2.2 ヒープとスタック

        Java プログラムでは、オブジェクトが作成されると、そのインスタンス データがヒープに格納され、オブジェクト参照がスタックに格納されます。各 Java メソッドは、メソッドのローカル変数、オペランド スタック、メソッド出口などの情報を格納するスタック フレーム (Stack Frame) を作成し、スタック フレームもスタックに格納されます。

        Java メソッドが呼び出されると、JVM はスタック内に新しいスタック フレームを作成し、そのスタック フレームをスタックの最上位にプッシュします。メソッドの実行が完了すると、JVM はスタック フレームをポップし、メモリ領域を再利用します。

        2.3実行エンジンとメソッド領域

        実行エンジンは、Java バイトコードを実行し、それをコンピュータが実行できる機械命令に変換する役割を果たします。バイトコードを実行する前に、実行エンジンはメソッド領域でバイトコードや定数などの情報を検索し、それらをランタイム定数プールにロードする必要があります。

        2.4ネイティブ メソッド インターフェイスとネイティブ メソッド スタック

        Java プログラムが C/C++ で記述されたネイティブ メソッドを呼び出す必要がある場合、JVM は Java パラメータを C/C++ パラメータに変換し、ネイティブ メソッドを呼び出します。ネイティブ メソッドの結果は Java プログラムに返されるため、C/C++ の結果を Java の結果に変換する必要があります。

        ネイティブ メソッド インターフェイスは、Java プログラムで C/C++ で記述されたネイティブ メソッドを呼び出すメカニズムを提供し、Java プログラムが基礎となるシステムと対話できるようにします。

3. クラスローダーの動作原理とクラスロードのプロセス

        クラス ローダー (ClassLoader) は JVM の重要な部分であり、ディスクやネットワークなどの外部ストレージから JVM のメモリに Java クラスをロードする役割を果たします。クラスローダーは「親委任モデル」を採用しています。つまり、クラスをロードする必要がある場合、最初に親クラスローダーにクラスの検索を委託し、最終的に起動クラスローダーに委任します。親クラス ローダーのいずれもクラスを見つけることができない場合、そのクラスはクラス ローダー自体によってロードされます。

クラスロードのプロセスには通常、次の 3 つの段階が含まれます。

  1. ロード: クラスのバイナリ データを検索してロードします。クラス ローダーは、まずクラスの完全修飾名を通じて対応する .class ファイルを検索し、次にバイナリ データをメモリに読み取り、対応する Class オブジェクトをメモリ内に作成します。同じクラスは JVM に 1 回だけロードされることに注意してください。

  2. リンク: クラスのバイナリ データを JVM のランタイム環境にマージします。接続フェーズは 3 つのステップで構成されます。

  • 検証: クラスのバイナリ データが JVM 仕様に準拠しており、セキュリティ ホールがないことを確認します。
  • 準備: クラスの静的変数にメモリを割り当て、デフォルト値を設定します。
  • 解決策: シンボリック参照を直接参照に置き換えます。つまり、クラス、フィールド、メソッドなどの参照をメモリ アドレスに変換します。
  1. 初期化(Initialization):クラスの静的変数に初期値を代入し、クラスの静的コードブロックを実行します。JVM では、クラスの初期化はスレッドセーフな操作であり、クラスが 1 回だけ初期化されることが保証されます。クラスに親クラスがある場合は、親クラスが最初に初期化されます。

        JVM はクラスを使用する必要がある場合にのみクラスをロードして初期化することに注意してください。このメカニズムは「遅延ロード」と呼ばれます。同時に、JVM は動的クラス ロード メカニズムもサポートしており、プログラムの実行中に Java リフレクション メカニズムを通じて新しいクラスをロードし、JVM に追加できます。

4. バイトコード命令セットの基本構文と使用法

        Java コードはコンパイラによってコンパイルされた後、クロスプラットフォームの中間コードであるバイトコード (Bytecode) に変換されます。バイトコード命令セットは、Java 仮想マシン (JVM) が認識して実行できるコード形式です。バイトコード命令セットは簡潔かつコンパクトで、基盤となるハードウェア アーキテクチャとは何の関係もないため、さまざまなプラットフォームで実行できます。

        バイトコード命令セットは単一バイトの命令で構成され、各命令にはオペレーション コード (Opcode) と 1 つ以上のオペランドがあります。Java 仮想マシンは、一連のバイトコード命令を実行することによって Java プログラムの実行を完了します。

以下は、バイトコード命令セットの基本的な構文と使用法です。

        4.1 ロードおよびストア命令

  • ローカル変数テーブルからオペランド スタックに値をロードします: iload、dload、aload など。
  • オペランド スタックからローカル変数テーブルに値を保存します: istore、dstore、astore など。

        4.2 操作説明

  • バイナリ演算命令: iadd、dadd、isub、dsub、imul、dmul、idiv、ddiv、irem、drem など。
  • ビット操作命令: ishl、ishr、iushr、iand、ior、ixor など。

        4.3 型変換命令

  • 整数値を他の型 (i2d、i2l、i2f など) に変換します。
  • 浮動小数点値を他の型 (d2i、d2l、d2f など) に変換します。
  • 長整数値を他の型 (l2i、l2d、l2f など) に変換します。

        4.4 制御コマンド

  • 条件付きジャンプ命令: ifeq、ifne、iflt、ifgt、ifle、ifge など。
  • 無条件ジャンプ命令: goto、goto_w など。
  • 戻りコマンド: ireturn、dreturn、areturn など。

        4.5 オブジェクト操作命令

  • 新しいオブジェクトの作成命令: new、newarray、anearray など。
  • フィールド操作命令: getfield、putfield、getstatic、putstatic など。
  • メソッド呼び出し命令: invokevirtual、invokespecial、invokestatic、invokeinterface など。

        一般に、バイトコード命令セットは、Java プログラムを実行するための Java 仮想マシンの基本的な構文と使用法を提供し、Java プログラムのクロスプラットフォーム動作の重要な保証の 1 つでもあります。

5. JITコンパイラとAOTコンパイラ

        JIT コンパイラーと AOT コンパイラーはどちらもコードをマシンコードに変換するツールですが、その動作方法とメリットとデメリットには大きな違いがあります。

        JIT コンパイラー (ジャストインタイム コンパイラー) は、プログラム実行中にリアルタイムで実行できるように、バイトコードをローカル マシン コードにコンパイルします。JIT コンパイラは、プログラムの実際の実行条件に応じてホット コードを最適化し、プログラムの実行効率を向上させることができます。JIT コンパイラーには次のような利点があります。

  • ジャストインタイム コンパイルにより、プリコンパイルによる長い起動時間が回避されます。
  • 動的コンパイルは、プログラムの実際の動作に応じて最適化され、プログラムの実行効率が向上します。
  • Java 仮想マシンと密接に組み合わされることで、プログラムの移植性と互換性が向上します。

JIT コンパイラーの欠点は次のとおりです。

  • コンパイル時間が長くなり、プログラムの応答時間に影響を与える可能性があります。
  • 1 回だけ実行される一部のコードの場合、JIT コンパイラは最適化せず、パフォーマンス リソースの一部を無駄にします。
  • JIT コンパイラはより多くのメモリ領域を消費します。

AOT コンパイラ (Ahead-Of-Time コンパイラ) は、プログラムを実行して実行可能ファイルを生成する前に、Java バイトコードをローカル マシン コードにコンパイルします。AOT コンパイラは、静的コンパイルによりプログラム全体を最適化し、プログラムの実行効率を向上させることができます。AOT コンパイラの利点は次のとおりです。

  • コンパイル時間と起動時間の短縮。
  • グローバル最適化を実行してプログラム全体を最適化し、プログラムの実行効率を向上させることができます。
  • プログラムは Java 仮想マシンがなくても実行できます。

AOT コンパイラの欠点は次のとおりです。

  • 動的最適化が欠如しているため、プログラムの実際の動作を最適化することは不可能です。
  • 移植性と互換性の問題が発生する可能性があります。
  • 多くのディスク容量を消費するため、リソースに制約のある環境に適用するのは困難です。

        まとめると、JIT コンパイラと AOT コンパイラには実装方法や長所と短所が異なり、それぞれが異なるシナリオに適しています。Java 仮想マシンでは、動的な最適化と移植性の向上を実現できる JIT コンパイラが主流のコンパイラですが、組み込みシステムやモバイル アプリケーションなどの特定のシナリオには、AOT コンパイラの方が適しています。

 ようこそ: http://mumuxi.chat/

おすすめ

転載: blog.csdn.net/zz18532164242/article/details/130543436