クラスローディング:
- クラスローディングの最終成果物は、ヒープにある
Class
オブジェクトです Class
オブジェクトはメソッド領域のクラスのデータ構造をカプセル化し、メソッド領域のデータ構造にアクセスするためのJAVAプログラマへのインターフェースを提供します- クラスローダーのタイプ:
- Java仮想マシンに付属するローダー
(1)C ++で記述されたルートクラスローダー(ブートストラップ)は、Javaコードでクラスを取得できません
(2)拡張クラスローダー(拡張)、Javaコードを使用して
(3)システム(またはアプリケーション)クラスローダー(システム)、Javaコードを使用 - ユーザー定義のクラスローダー
(1)java.lang.ClassLoaderのサブクラス
(2)ユーザーは
クラス3の読み込みメソッドを定義できます。クラスローダーは、クラスが「最初に使用される」のを待ってから読み込む必要はありません。
(1)jvm仕様では、クラスの使用が予想されるときに、クラスのロードでクラスをプリロードできます。.Class
ファイルが欠落しているか、プリロードプロセス中にエラーが発生した場合、クラスローダーは、プログラムがクラスを最初にアクティブに使用するときにのみクラスを使用する必要がありますエラーを報告する(LinkageErrorエラー)。
(2)クラスがプログラムによってアクティブに使用されていない場合、クラスローダーはエラーを報告しません
(3)クラスがロードされた後、接続フェーズに入ります。接続は、メモリに読み込まれたクラスのバイナリデータを仮想マシンのランタイム環境にマージすることです。
- Java仮想マシンに付属するローダー
クラスの確認:
- クラスファイルの構造検査:クラスファイルがJavaファイルの固定形式に従っていることを確認します。
- セマンティックインスペクション:クラス自体がJava言語の文法要件に準拠していることを確認します。たとえば、最終的な型クラスにサブクラスがなく、最終的な型メソッドが上書きされていないことを確認します(悪意のあるユーザーによる悪意のある操作を防止するため)。
- バイトコード検証:バイトコードストリームがJava仮想マシンで安全に実行できることを確認します。バイトコードストリームは、Javaメソッド(静的メソッドとインスタンスメソッドを含む)を表します。これは、オペコードと呼ばれる1バイトの命令のシーケンスであり、各オペコードの後に1つ以上のオペランドが続きます。バイトコード検証ステップは、各オペコードが有効かどうか、つまり、有効なオペランドがあるかどうかをチェックします。
- バイナリ互換性の検証:相互に参照されるクラス間の調整を保証します。たとえば、クラス
Worker
のgoWork()
メソッド内でCar
クラスのメソッドが呼び出されrun()
ます。Java仮想マシンはWorker
クラスを検証するときに、Car
クラスのメソッドがメソッド領域に存在するかどうかを確認しrun()
ます。存在しない場合(Worker
クラスCar
のバージョンとクラスに互換性がない場合、この問題が発生し、NoSuchMethodError
エラーがスローされます)
クラスの準備:
準備段階では、Java仮想マシンがクラスの静的変数にメモリを割り当て、デフォルトの初期値を設定します。例えば、以下Simple
のクラス、準備フェーズは、int
静的変数のタイプは、a
割り当てられた4
メモリ空間のバイトを、デフォルト値が与えられます0
。それはlong
、静的な型の変数のb
割り当て8
メモリ空間のバイト、及びデフォルト値を与え0
public class Simple {
private static int a=1;
public static long b;
static {
b=2;
}
}
クラス解決ステージ:
解析フェーズでは、Java仮想マシンがクラスのバイナリデータのシンボリック参照を直接参照に置き換えます。たとえばWorker
、クラスのgoWork()
メソッドはCar
クラスのメソッドで参照されrun()
ます。
public void goWork(){
ca.run();//表示符号引用
}
Worker
バイナリデータクラス含むCar
のrun()
で構成されてシンボリック参照の方法、run()
完全なクラス名および関連する方法記述子組成物。解決フェーズでは、仮想マシンがこのシンボル参照を、メソッド領域のCar
クラスのrun()
メソッドのメモリ位置を指すポインターに直接置き換えます。このポインターは直接参照です。
クラスの初期化:
1.初期化フェーズでは、Java仮想マシンがクラス初期化ステートメントを実行し、初期値をクラスの静的変数に割り当てます。プログラムでは、静的変数を初期化する方法が2つあります。
- 静的変数の宣言で初期化する
- 静的コードブロックで初期化します。
たとえば、次のコードでは、静的変数a
との両方b
が明示的に初期化されていますが、明示的に初期化されていc
ない場合、デフォルトでデフォルト値が保持されます0
public class Simple {
private static int a=1;
public static long b;
public static long c;
static {
b=2;
}
}
2.クラス初期化のステップ:
- このクラスがまだ使用可能な場合は
没有加载和连接
、最初にロードして接続します - クラスに直接親クラスがあり、親クラスが初期化されていない場合は、最初に直接親クラスを初期化します
- クラスに直接初期化ステートメントがある場合は、これらの初期化ステートメントを順番に実行します。
3.クラス初期化のタイミング:
Java仮想マシンがクラスを初期化するとき、そのすべての親クラスを初期化する必要がありますが、このルールはインターフェースには適用されません。
- クラスを初期化するとき、最初に、それが実装するインターフェースを初期化しません
- インターフェースが初期化されるとき、その親インターフェースは最初に初期化されない
ため、そのサブインターフェースまたは実装クラスの初期化のため、親インターフェースは初期化されません。インターフェイスを初期化します。
使用フェーズ:
クラスの使用には、オブジェクトのインスタンス化、ガベージコレクション、オブジェクトの終了の3つのステップがあります。
- オブジェクトのインスタンス化:これは、実行クラスのコンストラクターのコンテンツです。クラスに親クラスがある場合、JVMはまず、親クラスのコンストラクターを表示または暗黙的に実行し、親クラスのインスタンス変数用のスペースをヒープメモリに作成します。既定の初期値を割り当て、コンストラクタコードの内容に従って実際の値をインスタンス変数自体に割り当てます。次に、変数を参照してオブジェクトの最初のアドレスを取得し、オブジェクトを操作してインスタンス変数とメソッドを呼び出します。
- ガベージコレクション:オブジェクトが参照されなくなると、仮想マシンによって特別なガベージマークが付けられ、ヒープ内のGCコレクションを待機します
- オブジェクトの終わり:オブジェクトがGCによってリサイクルされると、オブジェクトは存在しなくなり、オブジェクトの寿命が終わります
アンインストール段階:
つまり、クラスのライフサイクルが最後のステップに達しました。プログラム内のクラスへの参照はなくなり、クラスはJVMによってガベージコレクションされ、ライフは終了します...