ルートを共有するためのJava JVMクラスローディング機構、JVM関連する概念を学ぶための良いプログラマ
- JDK <BR>
JDK(Javaの開発キット)は、Java開発キットは、Java開発者の集まりコンパイルやプログラムのデバッグのための手順のセットです。 - <BR> JRE
JRE(JavaランタイムEvironment)は、Java Runtime Environmentは、Javaプログラムを実行するためのプラットフォームであり、すべてのJavaプログラムは、このプラットフォームで実行することができます。 -
JVM <BR>
JVM(Java仮想マシン)は、Java仮想マシン、コンピュータによって実行される機能をシミュレートする仮想計算機コードの外で、それのような、独自のハードウェアアーキテクチャを有するプロセッサ、スタック、レジスタなど、ならびにそれら自身異なるオペレーティング・システム上の命令のセットは、Javaプログラムは、異なるオペレーティングシステム上で実行できる可能、JVMインストールすることができ、JVMは、Javaのクロスプラットフォームの機能を実現することです。
プロセスのJVMがクラスをロードし
ますが、コンパイルして実行する必要があり、我々はJavaプログラムは、後に開発、実行、JVMは、クラスのロード処理を担当しています。<BR>
プロセスクラスローダは、に分かれています。- ロード
- 検証
- レディ
- 解決
- 初期化
特定のクラスローディング手順
、これらのプロセスの下で以下に詳細に説明します。 - ロード<BR>
完了するために、クラスをロードするプロセスで: - 修飾子クラスのフルネームによると、クラスのバイナリストリームを取得、ストリームは、ディスク上のクラスから取得したjarファイルは、また、ネットワークから取得することができますすることができます。
- 動的記憶構造場合メソッド領域に静的ストレージ操作のクラスの構造
- ヒープメモリ内の対応のjava.lang.Classオブジェクトを作成するために、入口領域と方法
- <BR>確認し
完成されたクラスをロードした後、以前のClassオブジェクトで生成された情報は、JVMの安全を危険にさらすしないことを保証し、検証プロセスを、入力します。<BR>
側面を検証する必要があります。 - ファイル形式の検証は、仕様クラスバイトストリームファイルフォーマットの準拠を検証することで、仮想マシンの処理の現在のバージョンであることができます。マジックナンバーは、0xCAFEBABEかどうかを確認するために、メジャーおよびマイナーバージョン番号が現在の仮想マシンの処理範囲である等定数プール、一定サポートされていない一定のタイプが存在する場合、主な目的は、検証フェーズ入力バイトを確保することです後者の3つが基づいていることを検証フェーズメモリ領域の設定方法を行うように適切に解析し、処理領域に格納されたフローは、この段階で認証され、バイトストリームは、メモリ領域の格納方法に入ります。
- メタデータ検証情報は、Java言語仕様を記述した情報の遵守を確保するために、バイトコード意味解析を説明しています。検証が含まれる:親クラスかどうか、このクラスの親が許可され継承されたクラスを継承するかどうか、クラスは抽象クラスではないかどうか、その親クラスまたはインタフェースの実装要件のすべてのメソッドを実装している場合。
- バイトコード検証、主なタスクは、実行時にメソッドのバリデーションクラスは安全性を危険にさらす、仮想マシンの行為をすることはありません保証するために、データ・フローと制御フロー解析です。バイトコードメソッド本体は、クラスのバイトコード検証に合格しない場合、それは確かに問題です。しかし、バイトコード検証によって、メソッドの本体は、それが必ずしも安全で説明できない場合。
- 直接参照へのシンボリック参照は、このコンバージョンアクションは、「分析段階」で開催される際にシンボリック参照の検証は、仮想マシンで行われます。シンボリック参照クラス、フィールドおよびメソッド、対応するクラスを見つけることができれば命名機関を参照して説明検証記号列、メソッド指定されたフィールド記述子クラス名とフィールドの簡単な説明に準拠した方法があるかどうかと現在のクラスにアクセスできるかどうか、アクセシビリティ(プライベート、保護、公共、デフォルト)。
- <BR>準備
準備フェーズ方法は、静的クラス変数のためのメモリ領域を割り当て、デフォルト値を割り当てます。public static int count = 100;
例えば:準備段階で上記カウント変数が0に割り当てられ、その後、初期化中に100に割り当てられます。
- <BR>解決
構文解析ステージが直接参照を置き換えるプロセスへのシンボリック参照の定数プールへの仮想マシンです。- 基準シンボル(記号参照)<BR>
参照に記載されたシンボルの特定のセットへのシンボリック参照は、リテラルシンボルは、任意の形態であってもよく、限り目標を使用するように明確に位置付けることができます。シンボル参照は、仮想マシンを達成するためのメモリレイアウトとは何の関係もない、目標は必ずしもメモリにロードされた基準ではありません。 - 直接参照(直接参照)<BR>
直接参照は、オブジェクトへの直接ポインタ、相対オフセットまたは間接的にターゲットを処理するために標的化され得ます。メモリレイアウトへの直接参照は、あなたが直接参照を持っている場合、対象の参照が既にメモリに存在している必要があり、仮想マシンの実装に関連しています。
- 基準シンボル(記号参照)<BR>
- 初期<BR>
クラス初期化が完全にローディングフェーズにおいて、仮想マシン制御およびユーザアプリケーションによって支配され、残りのアクションに参加するために自己定義されたクラスローダによって以外に加えて、クラスローディングプロセスの前に、クラスをロードするプロセスの最終ステップです。初期化フェーズに、実際にJavaコードで定義されたクラスを開始しました。<BR>
初期化フェーズは、クラスのコンストラクタ<clinit>()メソッド中に行われます。<clinit>()メソッドは、すべてのクラスとの文のブロック(静的{}ブロック)を生成文をマージの静的変数のコンパイラクラス割り当て操作によって自動的に収集されます。
だから、ときの初期化にそれを実行するには? - クラスのインスタンスを作成します。
- アクセスクラス(定数、最終修正を除く)静的変数
理由:定数特別な変数、コンパイラはプロパティ値ではなく、治療するとして扱いますので。 - アクセスクラスの静的メソッド
- リフレクタ(Class.forNameの( "com.test.Person"))
- クラスを初期化すると、クラスがまだ父親の初期化、親クラスを初期化するための最初の呼び出しを見つけていません
-
仮想マシンが起動すると、クラスの初期化にmain()メソッドの定義
コードその場合は、
私たちが顔の質問を見て、クラスローディング機構を理解します:public class MySingleton { private static MySingleton singleton = new MySingleton(); public static int count1 = 0; public static int count2; private MySingleton(){ count1++; count2++; } public static MySingleton getInstance(){ return singleton; } public static void main(String[] args) { MySingleton singleton = MySingleton.getInstance(); System.out.println("count1-->"+MySingleton.count1); System.out.println("count2-->"+MySingleton.count2); } } 上面的结果,大多数同学可能认为两个静态变量都是1,结果比较意外:
COUNT1 - > 0
COUNT2 - > 1这是为什么呢?下面我们来分析下:
- まず、準備段階のクラスの静的変数のデフォルト値を割り当てます知っている:<BR>
シングルトン= NULL;
COUNT1 = 0;
COUNT2 = 0; - <BR>:のgetInstance静的メソッド呼び出しクラス、クラスの初期化がトリガされたとき、その後、新しいMySingleton()コンストラクタメソッド呼び出しを行う
= COUNT1が1であり;。
COUNT2 1 =;。 - 値1を保持するために全く割り当てCOUNT2ない、COUNT1は0を割り当て、初期化変数に値を代入していき、結果は:<BR>
COUNT1 = 0;
COUNT2 = 1;
要約
JVMは、独自のハードウェアやソフトウェア、JVMと、コンピュータシミュレーションのコードであります負荷を達成し、Javaクラスを実行するために、具体的なロードプロセスがあります。ロード、検証、準備、分析、5つのステップを初期化します。