- 深さ[研究ノート]仮想マシンのクラスローディング機構のJava仮想マシンVII章の理解

クラスローディング機構

Java型を形成する仮想マシンのメモリにクラスファイルからロードされたクラスを記述し、データを検証するデータ、及び初期化を解析変換は、仮想マシンのクラスローディング機構である仮想マシンとして使用することができます。

ローディング、検証、製造、解像度、初期設定、使用、アンインストール:JVMクラスローダーは、5つのプロセスに分割されています

 

 

読み込んで配列確認の準備、初期化およびアンロード5つのフェーズが決定され、クラスのロード処理がステップによって、この注文ステップで開始し、必ずしも相を解決してはならない。それができるいくつかのケースでは、初期化フェーズの後その後、(動的バインディングまたは遅延バインディングと呼ばれる)は、Java言語のサポート結合時間を実行するために始めました

ロード

.classファイルは(必ずしもの.class。ZIPパッケージが取得したネットワークであってもよい)は、主にロードされたバイトのバイナリストリームは、JVMに読み込ま。
ローディングフェーズにおいて、JVM完全三つ:
1)完全修飾クラス名が取得したクラスバイナリバイトストリーム;
2)ランタイムデータエリア構造方式にバイトストリームで表される静的記憶構造。
3)のjava.lang.Classこのクラスの様々なデータ・アクセス・エントリ領域法として、メモリ内のオブジェクトクラスを生成します。

接続

検証

最初のステップは、主にバイトの入力ストリームは、JVMの仕様に沿って装填されていることを確認するために、接続フェーズを確認することです。
位相が動作テストの次の4つの段階を完了する検証:
1)ファイル形式のバリ
(Java言語仕様を満たす)メタデータの検証)2
論理3)バイトコード検証(法的セマンティック決意プログラム)
4)(参照シンボルを検証しますさらなる分析が正常に行うことができることを確認し、接続の第三相における場合の変換動作、直接参照シンボル参照に、仮想マシンで発生した-分析的検証の位相基準シンボルを発生するクラス自体として見ることができますマッチング情報チェック用外部(定数プール基準シンボル))

レディ

第二のステップは、主方式エリア内の静的変数のためのメモリを割り当て、接続相を調製し、デフォルトの初期値を設定することです。

解決

分析第三のステップは、接続フェーズで、仮想マシンプロセスの定数プールは、直接参照シンボリック参照を置き換えられます。

初期化

初期化フェーズは、代入文の手順に従ってクラス変数のクラス、主に活性割り当てをロードするプロセスの最終ステップです。
注:
1)が親クラスであり、親クラスが初期化されていない、初期の親が行く;
2)その後、サブクラス初期化ステートメント。

とき私は、クラスを初期化する必要がありますか?

唯一無二の存在です。

1)クラスが初期化されていない場合は、このバイトコード命令は、初期化がそれをトリガーするために必要とされる新しい、getstatic、putstatic invokestaticまたは4に遭遇しました。これは、最も一般的なシナリオは、Javaコードでの4つの命令を生成します。クラス(最終修正の静的フィールドを読んだり設定するときにオブジェクトをインスタンス化する新しいキーワードを使用して、結果は静的の定数プールにコンパイルされていますときフィールド)を除いて、だけでなく、授業時間の静的メソッドを呼び出します。
時間2)使用java.lang.reflectのパッケージのアプローチは、クラスが初期化されていない場合、あなたはその初期化をトリガーする必要がある、というクラスを反映させます。
3)私たちは、親クラスが初期化されていない見つけた場合クラスは、初期化されるときは、親クラスのトリガ初期化する必要があります。
4)仮想マシンの起動、ユーザーのニーズは、そのクラスのメソッド(メイン(含有))を実行するメインクラスを指定する場合、仮想マシンはこのマスタークラスを初期化します。
動的言語サポートを使用する場合、分析の最後の例java.lang.invoke.MethodHandle REF_getStatic、REF_putStatic、REF_invokeStatic方法ハンドル、およびこの方法ハンドルクラスの結果が初期化されていない対応する場合は5)JDK 1.7は、それが必要です最初の初期化をトリガします。

サブカテゴリーで親クラスの静的フィールドを参照し、サブカテゴリーは、初期化させません

配列定義によってクラスを参照するために、初期化のこのタイプをトリガしません

コンパイル時定数は、定数プールのクラスに入金されますと呼ばれ、自然のクラス定数の定義には直接の言及はありません、それがトリガー初期クラスは、定数を定義していないだろう。

クラスローダ

クラスローダは、負荷段のバイナリバイトストリームが取得される機能です。

JVMクラスローダーは、次の3つのシステムを提供します。

  • このようrt.jarのようトップレベルのクラスローダがロードJAVA_HOME \ libディレクトリに責任がある、または-Xbootclasspathにより、パスのパラメータを指定し、仮想マシンのファイル名の識別によって認識されている(:スタートクラスローダ(ブートストラップクラスローダ) )クラス。
  • 拡張クラスローダ(拡張クラスローダ):JAVA_HOME \ libに\ extディレクトリ、またはのjava.ext.dirs図書館システム変数で指定されたパスをロードするための責任。
  • アプリケーションクラスローダ(アプリケーションクラスローダ):また、システムクラスローダーとして知られているが、()getSystemClassLoaderを介して取得することができ、ユーザーのパス(クラスパス)上のライブラリをロードするための責任があります。なしカスタムクラスローダ場合は、通常、これはデフォルトのクラスローダです。

クラスローダの階層関係を次のように

クラスローダ委譲モデルとの間のこの階層関係は、両親と呼ばれます。
ブートクラスローダ(ブートストラップクラスローダ)のトップを必要とする親委任モデルに加えて、クラスローダの残りの部分は、それ自身の親クラスローダを持っている必要があります。クラスローダは、一般的に達成するための継承ではなく、の組み合わせで親子関係。

両親は、プロセスモデルを委任することができます

クラスはクラスローダが要求を受信した場合には、彼は、ブートクラスローダ(ブートストラップクラスローダ)まで、層によってように転写層、親クラスローダにこの要求をロードするために行くが、このクラスローダ委譲しません。
親クラスローダがこの要求をロードできない場合にのみ、子ローダは、独自のをロードしようとします。

両親デリゲートコードモデルの実装

親委譲モデルコードは、ここではjava.lang.ClassLoaderのloadClass()メソッドを集中します。
1)クラスがロードされているかどうかを最初にチェックではなく、親クラスローダのloadClass()メソッドを呼び出し、
親クラスローダが空の場合は2)を、親ローダとしてデフォルトのブートクラスローダー;
3)親クラスローダならClassNotFoundExceptionが後の失敗は自分にfindClass()メソッドを呼び出して、スローされます。

loadClassソースコードは次のとおりです。

保護された同期クラス<?>はloadClass(文字列名、ブール決意)は、ClassNotFoundExceptionがスロー{
    クラスがロードされているかどうかを// 1つのまずチェック
    クラスC = findLoadedClass(名);
    IF(C == NULL){
        {試します
            もし(親!= NULL){
             2 @親クラスローダのloadClass()メソッドを呼び出していません。
                C = parent.loadClass(名前、偽);
            } そうしないと {
            //親クラスローダ3が空の場合は、親クラスローダとして、デフォルトのブートローダー。
                C = findBootstrapClass0(名);
            }
        }キャッチ(ClassNotFoundExceptionが電子){
           // 4の後に親が負荷に失敗した場合は、ClassNotFoundExceptionがスローされます
            C =にfindClass(名);
        }
    }
    IF(解決){
        // 5と、その後は、独自にfindClass()メソッドを呼び出します。
        resolveClass(C);
    }
    Cを返します。
}

  

破壊両親委譲モデル

様々なクラスの団結の問題に親委任モデルの優れたソリューションは、基本クラスをロードしました。すなわち、ローダによってロードされた上流階級の塩基です。
基本クラスのロードは、コールバックユーザーコード、およびこれらのユーザーコードを認識しないクラスローダのトップを必要とする場合、どのようにそれを行うには?そして、あなたは親委任モデルを破壊する必要があります。

参考ます。https://my.oschina.net/u/1458864/blog/2004785

おすすめ

転載: www.cnblogs.com/mcq1999/p/12130287.html