JVMがロードする必要があるのは、.classファイルまたは他のフォームの形式であるバイナリストリームです。読み込み基準に従って設計すると、大きな問題はありません。
以下は、主にメカニズムと標準の2つの問題を分析しています。
まず、変数の読み込みメカニズムに似たJavaクラスファイルのロードメカニズムを取りましょう。最初にクラスファイルをメモリにロードし、次にデータを検証し、解析し、初期化し、最終的に仮想マシンが直接使用できるJavaタイプを形成します。 JavaはJITメカニズムを採用しているため、ロードが遅くなりますが、その利点は明らかであり、柔軟性が高く、動的荷重と動的接続をサポートします。
次に、クラスの読み込みプロセスについて話しましょう。
クラスロードの基本的なプロセスは次の順序ですが、一部は厳密にはこの順序ではなく、一部は障害のある順序です。たとえば、動的荷重には初期化と解析が必要です。
1。読み込み
決定するのは仮想マシン次第ですが、次のフェーズを実行するために上記のフェーズが実行される場合もあります。
この時点で、仮想マシンは3つのことを行います。
まず、完全な資格のある名前を使用して、ファイルのバイナリストリームを読み取ります。
次に、ファイル内の静的メソッドと変数をメソッド領域に入れます。
第三に、オブジェクトを生成し、アクセスポータルとしてヒープに入れます。
最初のものはバイナリストリームを読み取ることであり、どのファイルから読み取られるか、どこから読み取られているかは言わないことに注意してください。したがって、JAVAで強力なスケーラビリティを作成します。これは、JAR、ZIP、またはネットワークレイヤー、データベースレイヤーなどからの可能性があります。
主にオブジェクトとメソッド領域の宣言。
2。検証
バイナリフローが仮想マシンの要件を満たし、VerifyErrorを満たしていないことを確認してください。
まず、ファイル形式の確認、魔法の数字があるかどうか、およびJavaファイルの要件を満たしているかどうか。
第二に、メタデータの検証は、抽象クラスが直接インスタンス化されているかどうか、通常のクラスに間接的な親クラスオブジェクトなどがあるかなど、Javaコード仕様に準拠しているかどうか。第三に、バイテコード検証は、データフローと制御フローを分析し、存在しない命令を呼び出すかどうか、親クラスをサブクラスに割り当てるかどうか、このタイプのオブジェクトにオブジェクトを割り当てるかどうかなど、仮想マシンに害を与える動作がないことを保証します。
第4に、象徴的な参照検証、主にクラス、変数、および方法の説明が、ファイルが完全に適格な名前で見つけることができるかどうか、アクセス可能かなどを見つけることができるかどうかなどです。
主に内部構造を決定します
3。準備します
クラス変数に初期値を割り当てることは、通常、インスタンス変数に値を割り当てることなく、静的変数などの0値です。
4。分析
一定のプール内のシンボリック参照を直接参照に変換するプロセス。ここで述べたシンボリックリファレンスは変数タイプを指し、直接参照はオブジェクトに直接配置できるハンドルを指します。クラス、メソッド、フィールド、インターフェイス解析、完全な資格のある名前に従って関連するオブジェクトを取得し、そのタイプを取得します。クラスにアクセスできない場合、Illegalaccesserrorが投げられ、フィールドNosuchfielderrorは投げられません。
5。初期化
プログラムの要件に応じて、クラスと必要なリソースをロードします。状況は4つしかありません。次の操作を実行する前に積極的に初期化する必要があるため、最初に上記の4つのステップを実行する必要があります。
まず、新しいキーワードまたは静的キーワード、新しい生成オブジェクト、および静的な静的負荷を使用したクラスでは、これら2つは明らかに初期化されます。
第二に、クラスを使用する場合、それについてできることは何もありません。
第三に、反射クラスの方法は初期化する必要がありますよね?
第四に、メインメソッドを使用するクラスのメインクラス。他の受動的な初期化の状況を考慮する必要はありません。
小さな例:
パブリッククラスのスーパークラス{static {system.out.println( "superclass !!");} public static int value = 1;} public class subclassはsuperclass {static {system.out.println( "subclass !!");}} public class esticclassload {public static void main(String [] args) {system.out.println(subclass.value); superclass superclass = new subclass();}} superclass !! 1subclass !!実行結果は問題を示しています。サブクラスが親クラス変数を呼び出す場合、この時点でのコード関係はサブクラスとは何の関係もないため、サブクラスが初期化されません。サブクラスが初期化されると、親クラスが現在のメソッド本体で初期化されているため、親クラスは再び初期化されません。インターフェイスと親クラスの唯一の違いは、インターフェイスの初期化が親インターフェイスを必要とせず、親インターフェイスを使用した場合にのみ初期化され、同じクラスコンストラクターが生成されることです。
この時点で、クラスコンストラクターがロードされ、クラス内のすべての変数が初期化されます。もちろん、親クラスは子供クラスの前に初期化されます。
6。使用します
読み込み後、それを呼び出す方法、描画、計算など。
7。アンインストール
クラスはもはや呼ばれていません
2つのクラスが等しいかどうかは主に同じローダーを使用した最初のロードに依存し、2番目の完全に認定された名前アドレスは同じです
なぜ上記の質問をするのですか?次に、仮想マシンのローディングメカニズムについて説明します。
Java Virtual Machinesの観点からは、2つのクラスローダーがあり、1つはシステムローダー(Bootstrap ClassLoader)と呼ばれ、もう1つはカスタムローダー(拡張クラスローダー)と呼ばれます。これは2つに分割され、1つはアプリケーションローダーと呼ばれ、もう1つは拡張クラスローダーと呼ばれ、通常は前者にデフォルトです。また、アプリケーションの読み込みは、主に上記の3つのローダーによって行われます。 3つの関係は、アプリケーション>拡張子> bootsrapです。親委任メカニズムは、2つのペアの組み合わせを指します。チャイルドローダーは最初に親ローダーメソッドを呼び出し、ターゲットオブジェクトは子供ローダーを使用する前に見つかりません。
擬似コードは次のとおりです。
loadclass(string name、boolean resolve){class c = findloadclass()if(c == null){if(parent!= null)c = parent.loadclass(name、false); c = findbootstrapclassornull(name);} catch(classnotfoundexcection e){} if(c = = null)c = null)Javaは、Calling Classの論理をFindClassで書くことを主張しています。これは、親の委任メカニズムを通常使用するのに役立ちます。
1を破壊します。ロードクラスを書き直します
2。スレッドコンテキストローダーを使用して、親ローダーにチャイルドローダーメソッドを呼び出すようにします
破壊3。ホットロードに一般的に使用される方法は、クラスローダーをカスタマイズし、元のバグモジュール-OSGIを上書きすることです
ただし、カスタムローダー間のルールが混乱し、同時に互いに参照する問題がある場合、クラスは最終的には見つかりません。スレッドデッドロックとメモリリークが発生します。
プラグインとも呼ばれるホット修理に関しては、最も人気のあるものはHotfix、Nuwa、Droidfix、およびFixなどです。これらのフレームワークはGithubまたは他の場所で見つけることができます。原則は上記であり、メソッドは多様であり、構成、設定アクションなどを通じてカバレッジ、リダイレクトなどがあります。プラグインとして、次の条件を満たす必要があります。
1。独立してインストールできますが、独立して実行することはできません
2。後方互換性を拡大することができます
3.ホストプログラムでのみ実行でき、無効または交換できます
上記の例Java Advanced Virtual Machineロードメカニズムの説明は、私があなたと共有するすべてのコンテンツです。参照を提供できることを願っています。wulin.comをもっとサポートできることを願っています。