Javaクラスのロードおよびクラスのライフサイクル

クラスローダ

クラスローダとは何ですか

仕事をするためにクラスローダ:

  1. .classファイルクラスは、メモリ内領域におけるランタイムデータ領域方法をバイナリデータを読み出します
  2. java.lang.Classは、その後、メソッド領域のデータ構造をカプセル化するためのヒープ・オブジェクト、オブジェクトクラスを作成します。

最終製品のクラスのロード:

ヒープ領域に作成されたクラスオブジェクトは、二次包装のクラス・オブジェクト・クラスのデータ構造方法のゾーンに位置し、Javaプログラマに領域のデータ構造のためのインタフェースアクセス方法を提供します。

クラスのロードタイミング

クラスがロードされているものを学び、その後、どのような時にクラスは、それがロードされますか?

  1. クラスローダは、このカテゴリを再ロードするための新しい時間を待たずに、つまり、「最初のアクティブな使用」するクラスを待つ必要がないとき、それをロードします。
  2. JVM仕様では、それは、それが事前にロードされたクラスを使用することが期待されているクラスローダを可能にしますが、中に.classファイルが発生した場合は不足しているプリロードされたか、エラー、クラスが最初のプログラムを使用するためのイニシアチブをとる必要があるクラスローダがありますエラーを報告(LinkageErrorのエラー)
  3. 行方不明の.classクラスが積極的にプログラムを使用していない場合は、クラスローダはエラーを報告しません

負荷の.classは道をファイル

  1. ローカルシステムから直接ロード
  2. ネットワーク経由でダウンロードした.classファイル
  3. などのzip、jarアーカイブから.classファイルをロードします
  4. 独自のデータベースからファイルを抽出した.class
  5. 動的に.classファイルにコンパイルJavaソースファイル

クラスのライフサイクル

主なポイントを理解します:

  1. ロード、検証、準備、分析、5つのステージを初期化するなど、クラスローディングプロセス、。いくつかの時間は、リンク段階と呼ばれるこれらの三つの段階を解決するために、準備ができて、確認します
  2. 4つの段階のその中でも、ロード、検証、準備及び初期化配列が決定され発生し、ステージは、必ずしも、それはいくつかのケースでは、これは、実行時間をサポートするために、Java言語に縛られ、初期化段階の後に開始することができます解決されません(また、動的バインディングまたは遅延バインディングと呼ばれる)のセット。
  3. 追加のステージがあることに注意してください順に順次開始されているのではなく、完全またはこれらの段階は、一般的に、別の混合は、通常、実行中に別の段階でのステージを呼び出すか、アクティブに1と交差しているため、。

ロード

ロードクラスがロードプロセスの最初の段階で、主な仕事は、ロード・フェーズでは、バイナリデータの種類を見つけてロードするためにそれを行うことです、JVMは、この段階では3つのことを実行する必要があります。

  1. クラスの完全修飾名で定義されたバイナリバイトストリームを取得します。

  2. これは、ランタイムデータ構造領域法に静的記憶構造のバイトストリームを表します。

  3. このようなデータ領域のエントリへのアクセス方法として、このクラスのJavaヒープのjava.lang.Classオブジェクトの代表を生成します。

開発者は、両方のクラスローダを提供するためにシステムを使用することができるため、クラスローディング、ローディング・フェーズの他のステージに対する制御最強のステージである(具体的には、動作は、クラスローディング位相を取得バイトのバイナリストリームです)読み込みが完了している、あなたはまた、読み込みが完了するために、独自のクラスローダをカスタマイズすることができます。

ローディング段階が完了した後、外部記憶方式エリアに応じて仮想マシンに必要なバイトのバイナリストリーム上の仮想マシンの形式だけでなく、Javaヒープ内のクラスのjava.lang.Classオブジェクトを作成し、我々が通過できるようにこれらのデータアクセスオブジェクトエリア。

検証

認証は、リンク段階の最初のステップであり、それはロードされたクラスの正しさを保証することです

この段階の目的は、クラスに含まれる情報のバイトストリームファイルが自分自身の安全を危うくしません、現在の仮想マシンと仮想マシンの要件を満たしていることを確認することです。

検証フェーズは、検査操作を大まかに4つの段階を完了されます。

  1. ファイル形式の検証:クラスファイル形式に準拠してバイトストリームの検証;例えば:定数プールの種類の定数がある場合、初めか0xCAFEBABEは、仮想マシンの現在の処理範囲でメジャーとマイナーバージョン番号は、サポートされていません。 。

  2. メタデータの認証:説明バイトコード情報セマンティック分析(注:意味分析フェーズコントラストjavacコンパイラ)、Java言語仕様の要件の遵守を確実にするための情報が記載されており、例えば:クラスは、Java以外は、親クラスを持っているかどうか外.lang.Object。

  3. バイトコード検証:データフローと制御フロー解析プログラムのセマンティクスを決定するためには、正当な論理です。

  4. シンボリック参照の検証:分析操作が適切に行われることを保証します。

検証フェーズは非常に重要であるが、必ずしもそうではない、プログラムの実行には影響を与えません、繰り返し検証した後、参照クラスの場合、仮想マシンのクラスを減らすために、クラスの検証措置のほとんどをシャットダウンする-Xverifynoneパラメータを使用することを検討してくださいロード時間。

レディ

作業準備フェーズは、静的変数のクラスのためのメモリを割り当てることである(その静的変数に注意してください)、これらのメモリは、メソッド領域に割り当てられます、デフォルト値に初期化します。

次のポイントは、この段階に注意を払う必要があります。

  1. この時間は、メモリ割り当てクラス変数(静的)を含み、オブジェクトがインスタンス化されるときにJavaオブジェクトとして割り当てられたヒープ内のインスタンス変数、インスタンス変数を含んでいません。

  2. 典型的には、ここで設定した初期値は、値がJavaコードで明示的に与えられているのではなく、ゼロのデフォルト値のデータ・タイプ(例えば、0,0L、ヌル、偽、等)です。

栗の場合:

假设一个类变量的定义为:public static int value = 3;
那么变量value在准备阶段过后的初始值为0,而不是3,把value赋值为3的动作将在初始化阶段才会执行。
复制代码
  1. 明示的にその直接の使用を割り当てない場合は、基本的なデータ型、クラス変数(静的)とグローバル変数は、システムがそれをゼロのデフォルト値を代入し、ローカル変数のために、それは使用前にしなければなりません明示的に割り当てるか、時間をコンパイルしないでください。

  2. 修正のstatic final定数のと同時に、それが明示的に割り当て時に記載しなければならない、または時間をコンパイルしないでください

  3. しかし、定数の唯一の最後の変更は、次のいずれかを明示的に宣言するとき、使用を明示的にクラスの初期化を割り当てる必要があります前に、それはまた、明示的に、短期で、値(すなわち、コンストラクタ)を割り当てることができ、それを割り当てることができますシステムはそれをゼロにデフォルトの値を代入しません。

  4. 基準は、例えば、他のオブジェクトへの参照は、明示的にシステムに直接使用ゼロの値を割り当てられない場合、すなわちヌル、デフォルト説明する配列参照としてデータ・タイプへの参照です。

  5. 値がアレイの初期化中にアレイ内の各要素に割り当てられていない場合、前記要素は、対応するデータの種類に応じて、ゼロのデフォルト値が与えられます。

  6. 一定値プロパティクラスフィールド属性テーブル現在フィールド、すなわち場合、最終的な静的改変されながら、その属性ConstValue準備段階変数値で指定された値に初期化されます。

栗の場合:

假设上面的类变量value被定义为: public static final int value = 3;
编译时Javac将会为value生成ConstantValue属性,在准备阶段虚拟机就会根据ConstantValue的设置将value赋值为3。我们可以理解为static final常量在编译期就将其结果放入了调用它的类的常量池中
复制代码

解決

実行する段階を解析する直接参照に変換シンボル参照を入力することです

クラスまたはインタフェース、フィールド、メソッド、クラス、インタフェースメソッドのための主要な分析操作入力方法、及びシンボリック参照方法ハンドル7点クラス修飾子を呼び出します。シンボリック参照は、任意のリテラルであることができるターゲットを記述するためのシンボルの集合です。

直接参照は、間接又は測位対象ハンドルに対してオフセット、オブジェクトへの直接のポインタです。

初期化

初期化、静的変数のクラスのための正しい初期値を与え、メインクラス変数を初期化するための責任JVMクラスが初期化されます。

二つの方法でJavaクラスの変数に設定された初期値:

  1. あなたはクラス変数を宣言するときに初期値を指定します。

  2. 静的コードブロックを使用すると、クラス変数の初期値が代入され

JVMの初期化ステップ

  1. このクラスは、ロードと接続し、プログラムに接続されていない場合は、クラスをロードします

  2. 直接の親クラスが初期化されていない場合は、最初にその直接の親を初期化

  3. クラス初期設定ステートメント場合、システム順次初期設定ステートメントを実行します

クラスの初期化タイミング:

クラスのアクティブな使用は、クラスの初期化をリードし、このクラスがロードされていることに注意して、積極的に使用さの異なるクラスになる場合のみ、次の6つのものがあります。

  1. クラスのインスタンスを作成し、新しい方法であります

  2. アクセス静的クラスまたはインタフェースの変数、または静的変数の代入

  3. 静的メソッド呼び出しクラス

  4. リフレクタ(例えばClass.forNameの( "com.shengsiyuan.Test"))

  5. クラスのサブクラスを初期化し、親クラスが初期化されます

  6. Java仮想マシンは、マスタークラス、直接のjava.exeコマンドを実行するために、クラスのクラス(Javaのテスト)を開始するためにマークされ始めたとき

人生の終わり

以下の状況では、Java仮想マシンは、ライフサイクルを終了します

  1. でSystem.exit()メソッドの実装

  2. 通常のプログラム実行が終了

  3. 中止され、実行中に例外やエラーが発生しました

  4. オペレーティング・システム・エラーがJava仮想マシンを終了させるプロセスを引き起こしたので

おすすめ

転載: juejin.im/post/5d6dfcf551882559f971d796