インタビュアー:二つのプロセスの新しいオブジェクト?

オリジナルリンク: https://mp.weixin.qq.com/s?__biz=MzI3ODcxMzQzMw==&mid=2247491271&idx=3&sn=b0a6d3e23de32b9938abf2a3ee5b3ce9&chksm=eb539bf1dc2412e7d1dc2e4cb0a2314dd1119fe649246daf8e6a67b66aa668c0241a69765837&mpshare=1&scene=23&srcid=&sharer_sharetime=1571976595171&sharer_s

、それは最初のクラスの完全修飾名を経由してロードされますされていない場合、クラスは、最初のオブジェクトが属する表示されますで、新しいJavaオブジェクトは、メモリにロードされていません。クラス終了後ロードおよび初期化した後、作業オブジェクトを作成しています。

負荷およびクラスを初期化し、オブジェクトを作成します。私たちの最初の仮定は、新しいオブジェクトは、2つの工程に分けることができ、その場合、このタイプの最初の使用、ということです。

まず、クラスローディング手順(使用して第一級)

Javaは、我々はその作業工程を見て、ロード処理を説明する前に、クラスをロードするために、親委任モデルを使用するので、クラス:

両親は仕事のプロセスモデルがある委託:クラスローダ(クラスローダー)は、要求クラスがロードされている受信あれば、それは最初にこのクラスをロードしようとするために所有していませんが、それぞれを完了するために、親クラスローダに要求を委託しますレベルのクラスローダは、その検索に必要なものが見つかりませんでした(ので、すべての要求の究極の負荷が親クラスローダは、彼らが要求を完了することはできませんフィードバックをロードするときにのみ、ブートクラスローダのトップに転送されなければならない事実であります)クラスをロードする際、サブローダは、独自のをロードしようとします。

ロードを実行するときに、常にこれらのクラスの一つだけをロードする、効果的にクラスのグローバル一意性を確保するための能力、同じクラス名がより限定されたプログラムを表示され、クラスローダ:両親を使用する利点は、メカニズムを委託します。

1、ロード

クラスローダは、バイナリバイトの読み出しを担当するクラスの完全修飾名に応じてJVMの内部に流入し、そしてゾーンのランタイムメモリ領域の方法を記憶し、次にターゲットのJavaの対応する型に変換されます。 lang.Classオブジェクトインスタンス

2、検証

フォーマットの検証:クラスファイルの仕様かどうかを確認してください

セマンティック検証:最終的なサブクラスが含まれているようなタイプがマークされている検査、最終メソッドをチェッククラスのサブクラスで上書きするかどうか。

(例えば、同じメソッドシグネチャが、異なるメソッドの戻り値として)何の方法は、親と子のクラス間の書類の一部に対応していないではないことを確認してください

動作検証:データオペランドスタックは、記載されたタイプを指定するための完全修飾名が基準シンボルで配置することができるかどうかを確認し、通常の基準解像度の相で行わ(検証を行う定数プール内の様々なシンボルの正しい動作でなければなりません)上だけでなく、アクセス修飾子のクラスメンバーなどの情報へのアクセスを許可するかどうか

3、準備ができて

クラスメモリ空間の静的変数に割り当てられているすべて、および(オブジェクトがインスタンス変数は、この操作の範囲内ではありませんていないので)初期値を設定します

修飾された最終的な静的変数(定数)は、割り当てを指示します。

4、構文解析

直接参照(直接メソッドを呼び出すために、得られたクラスまたはフィールド、あるいはメモリ内のオフセットメソッドポインタ)に符号定数プールを、次いで、これは、初期化後に行ってもよいです。
コンテンツは静的にバインドする必要が解析します。//すべての方法が書き換えられないだろうと静的結合ドメインになります

2,3,4またはそれ以上の段階と3つのリンク段階まとめ、リンクステージは、バイナリデータのバイトストリームのクラスにJVMにロードされるかは、JVM動作状態に組み込まれています。

図5に示すように、初期化(父後サブ)

  • 4.1静的変数への代入

  • 静的コードブロック4.2を実行します

注:コードの静的ブロックはJVMを呼び出すことができます

複数のスレッドが同時にクラスを初期化する必要がある場合は、1つのスレッドのみだけ待機している他のスレッドを通知します、スレッドが唯一のアクティブなスレッドは、クラスの初期化を実行した後、残りを待つ必要があり、それらが初期化を実行できるようにすることができます。

親サブクラスへの依存のため、読み込み順序がクラスの親クラスローダサブクラス、同じ初期化をロードするようにします。親クラスの初期化、静的変数のサブクラスの値はまた、いくつかを持っている場合しかし、それはデフォルトです。

最後に、メソッド領域は、(定義静的変数と初期化コードブロック割り当てステートメント)、インスタンス変数は、インスタンスの初期化コード(割り当てステートメントを定義した静的クラス変数、クラスの初期化コードを含む現在のクラスのクラス情報を格納する際にインスタンス変数の定義そのような情報ブロック工法の一例)と、インスタンスメソッド、ならびに親クラスへの参照。

第二に、オブジェクトを作成します

図1に示すように、オブジェクトは、ヒープ内のメモリを割り当てる必要があります

メモリの割り当ては、このクラスと親クラスのすべてのインスタンス変数を含むが、任意の静的変数が含まれていません。

2、すべてのインスタンス変数のデフォルト値を割り当てます

この方法は、ヒープのインスタンス変数のコピー内に定義され、デフォルト値を割り当てます

図3に示すように、インスタンスの初期化コードが実行されます

初期化シーケンスは、次に、初期化され、再初期化サブクラスを初期化する例コードブロックを実行するために、第1の親クラスである場合、コンストラクタ

図4に示すように、同様の子供C =タイプ子参照変数CのC-引用定義の形で新しい子()とにアドレスを割り当てることがある場合、スタック領域内のオブジェクトのヒープ領域

親クラスのオブジェクトの各サブクラスは、オブジェクトへの参照を保持しているsuperキーワード内の親オブジェクトから呼び出すことができますが、外部からアクセスできないことに注意してください

彼は加えました:

参考例でインスタンスメソッドを呼び出して、情報の実際の型は、検索中のオブジェクトのメソッドを起動したとき、言葉は親クラスの型情報を探しに行くために見つけることができません。

すべての呼び出しを見つけるために、何度も通過するので、継承階層が深い場合には、この方法は、親クラスが上位比較に位置して呼び出すために、呼び出しの効率は、比較的低いです。この時間のほとんどは、システムコールの効率を最適化するために、仮想メソッドテーブルと呼ばれるメソッドを使用します。

いわゆる仮想メソッドテーブルが、である、クラスがロードされたときに、各テーブルのクラスを作成し、この表は親クラスを含むクラスのオブジェクトの動的バインディングすべてのメソッドとそのアドレスを含むが、この方法は、1つのレコードのみであり、サブクラスがオーバーライドされた後、親クラスのメソッドは、サブクラスのみが保存されます。ときに動的バインディング法によるオブジェクト、ちょうどそれぞれの親のための一つ一つを発見する必要がなく、それにルックアップテーブル。

エピローグ

、お互いを励まし、今お互いを奨励するために、これらの単語を取ります。より多くの仕事は、あなたが公式の第二世代でない場合より多くの幸運、豊かな第二世代、第二世代の赤、覚えておいてください:ハードワークがあなたの運命を変更する唯一のショートカットです。

著者:沈黙の弟

www.cnblogs.com/JackPn/p/9386182.html

おすすめ

転載: blog.csdn.net/zl1zl2zl3/article/details/102742383