前回の記事では Class ファイルについて説明しましたが、今回は仮想マシンがこれらの Class ファイルをどのように読み込むかについて説明します。 Class ファイル内の情報は、仮想マシンに入った後どうなりますか?これにはクラスロードメカニズムが関係します。
クラス読み込みメカニズムは、クラス ファイルからクラス データをメモリに読み込み、データを検証し、変換、解析、初期化し、最後に仮想マシンで直接使用できる Java 型を形成することです。 。この一連の処理はプログラムの実行中に完了します。
クラス ローダー
クラス ローダーは、以下の図の赤いボックス内の部分であり、完全修飾名を通じてこのクラスを記述するバイナリ バイトを取得します。 class.Stream を使用して、Java クラスを JVM のメモリ空間に動的にロードします。
#適用可能なシナリオ
配列クラスの場合、クラス ローダーを経由せずに Java 仮想マシンによって直接作成されます。
親委任メカニズム
親委任メカニズムは、クラス ローディングで使用されるメソッドです。クラスローダーがクラスロード要求を受信した場合、最初にクラス自体をロードしようとするのではなく、要求を親クラスローダーに委任して完了させます。これは、クラスローダーのすべてのレベルに当てはまります。親ローダーがリクエストを完了できないと報告した場合にのみ、子ローダーはそれを単独でロードしようとします。
現実に例えると、シャオミンはおもちゃの掘削機を買いたいと思っていますが、恥ずかしくて直接言えません。そこで、以下のような会話が行われました。 シャオミンは父親に「お父さん、掘削機は持っていますか?」と尋ねました。お父さんは言いました:いいえ
それからお父さんはおじいちゃんに尋ねました:お父さん、お父さん、掘削機を持っていますか?
おじいちゃんは言いました:いいえ
それからおじいちゃんはひいおじいちゃんに尋ねました:お父さん、お父さん、掘削機は持っていますか?
おじいちゃんは言いました:私もそうではありません。ひ孫さんに買ってもらいましょう。
その結果、シャオミンは喜んで自分でおもちゃの掘削機を購入しました。
カテゴリ
スタートアップ クラス ローダーは C で実装されており、仮想マシン自体の一部です。他のクラス ローダーは、仮想マシンとは独立して Java 言語で実装され、すべて抽象クラス java.lang.ClassLoader を継承します。
利点
String クラスを例に挙げます。ユーザーが自分で String クラスの実装を作成した場合でも、このクラスをロードするときは、JDK 内の元の String クラスをロードするために起動クラス ローダーに委任されるだけであり、カスタム String クラスはロードされません。これにより、システムのセキュリティが確保されます。 #クラスのロードはいつ実行されますか?クラスをすぐにロードする方法は次の 5 つだけです (1) new を使用してオブジェクトをインスタンス化する場合、クラスの静的フィールドを読み取るか設定する場合 (final によって変更され、すでにコンパイルされています) ) (結果が定数プールの静的フィールドに入れられる場合を除く); クラスの静的メソッドを呼び出すとき。 (2) java.lang.reflect パッケージのメソッドを使用してクラスへのリフレクション呼び出しを行う場合。クラスが初期化されていない場合は、最初にその初期化をトリガーする必要があります。 (3) クラスを初期化するときに、その親クラスが初期化されていないことが判明した場合は、最初に親クラスの初期化をトリガーする必要があります。 (4) 仮想マシンの起動時に、ユーザーは実行するメイン クラス (main() メソッドを含むクラス) を指定する必要があり、仮想マシンはまずメイン クラスを初期化します。 クラスロードプロセスの詳細説明 #開発者はカスタム クラス ローダーを通じて参加できます 初期化フェーズ # では、開発者のコードを実行して、クラス変数やその他のリソースを初期化します ( #1)。 #仮想マシンが完了する必要があること: (1) クラスの完全修飾名を使用して、このクラスを定義するバイナリ バイト ストリームを取得します。 (2) このバイト ストリームで表される静的ストレージ構造をメソッド領域の実行時データ構造に変換します。 (3) このクラスを表す java.lang.Class オブジェクトを、メソッド領域内のこのクラスのさまざまなデータへのアクセス エントリとしてメモリ上に生成します。 #2. 検証 ファイル形式検証、メタデータ検証、バイトコード検証、シンボル参照検証の 4 つのステップに分かれています。このうち、ファイル形式の検証はバイトストリームに対して直接動作し、残りの 3 項目はメソッド領域で実行されます。 3. 準備 この段階は、クラス変数に正式にメモリを割り当て、クラス変数の初期値を設定する段階です。メソッド領域に配置されます。注意点は 2 つあります。 (2) クラス変数が最終変更されていない場合、その初期値はデータ型のゼロ値になります。たとえば、int 型は 0、boolean 型は false です。例を挙げて説明します。 public static int value=123;
public static final int value=123;
現時点ではfinalがあるため、準備段階で値は123に割り当てられています。
4. 解析
解析フェーズは、仮想マシンが定数プール内のシンボル参照を次のものに置き換えるプロセスです。直接の参照。クラスまたはインターフェイス、フィールド、クラス メソッド、インターフェイス メソッドなどを解析できます。 シンボリック参照とは: シンボリック参照とは、クラス情報、メソッド名、メソッドパラメータなどの情報を含む文字列で、クラスのメソッドテーブルで使用されます。実際に使用する場合は、該当する方法を探してください。 直接参照とは: 直接参照はオフセットであり、 class メソッドのバイトコードの開始位置。 5. 初期化 このステージは、クラス変数とその他のリソースを初期化するために使用されます。これは、実行クラス コンストラクター()メソッド処理とは、クラス内に定義された Java プログラムコードが実際に実行を開始する処理です。 上記は、JAVA 仮想マシン クラスのロード メカニズムの詳細な説明です。その他の関連する質問については、PHP 中国語 Web サイトを参照してください: JAVA ビデオ チュートリアル
シンボル リファレンスは、このメソッドのいくつかの特性を示しています。これらの特性を使用して、対応するメソッドを見つける必要があります。直接引用とは、このメソッドがどこにあるかを直接伝えることを意味します。
以上がJAVA仮想マシン(JVM)の詳しい紹介(5) - クラスローディングの仕組みの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。