「Java仮想マシンの深い理解」 - オブジェクトの探査

負荷クラス:

Java仮想マシン仕様、義務のロードを開始するとき、ありません、しかし、それはいくつかの例厳格なルールを持っています

必须进行初始化(加载,验证,准备则需要在初始化之前开始)

  • 何のクラスが初期化されていない場合は、初期化がトリガされ、新しいgetstatic、putstatic、4またはinvokestaticバイトコード命令に遭遇します。
  • 第1のトリガの初期化、呼び出されたときに初期化されていない場合は、対向反射、パッケージアプローチをjava.lang.reflectの使用
  • クラスの初期化時、私たちは親クラスが初期化されていない見つけた場合、親クラスの最初のトリガの初期化。


クラスははるかにメモリをアンロードするまで、仮想マシンを起動するためにメモリにロードされてからは、そのライフサイクル全体、を含みます:

ロード(読み込み)、確認(検証)、製造(作製)、分析(解像度)、(初期化)を初期化する(使用する)を使用し、搬出(アンロード)7つの段階。まとめ(リンク)が接続特徴、検証、製造および解析。プロセスを以下に示します。


ロード

ロード・フェーズは、3つのことを行います。

  • クラスの完全修飾名で定義されたバイナリバイトストリームを取得するには。
  • これは、ランタイムデータ構造領域法に静的記憶構造のバイトストリームを表します。
  • このようなデータ領域のエントリへのアクセス方法として、このクラスのJavaヒープのjava.lang.Classオブジェクトの代表を生成します。

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

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

検証

それはバリデーションクラスのデータ形式、意味解析、検証作業をカバーして検証するために有効なバイトコードファイルであるかどうか、データ型のJVM仕様かどうかを確認します。

レディ

クラスの静的変数のメモリに割り当てられ、メソッド領域に割り当てられたメモリのデフォルト値を、初期化するには、次の点に注意を払う必要があります:

  • 本明細書でインスタンス変数は、Javaオブジェクトのインスタンス化とヒープに割り当てられている、可変メモリ割り当てのみクラス変数(静的)を含み、インスタンス変数を含んでいません。
  • ここでデフォルト値が代わりにコードが表示されている所定の値のデフォルトのデータ・タイプ(例えば、0,0L、NULL、偽)です。
  • 最終の静的修飾ながらConstatntValueプロパティクラスフィールド属性テーブル現在フィールド、すなわち場合は、属性ConstValue準備段階変数値で指定された値に初期化されます。

解決

解像度相を仮想マシンプロセスの定数プールはシンボリック参照直接参照、主修飾子クラスまたはインタフェース、フィールド、メソッド、クラス、インタフェースメソッド、タイプ方法の分析操作を置き換え、および方法は、クラスリファレンスシンボルの7点を扱うコールされます。シンボリック参照は、任意のリテラルであることができるターゲットを記述するためのシンボルの集合です。

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

初期化

本当のスタートがあり、この段階では、クラスのロード処理の最後の相で初期化しますjava代码主导あなたが実行している場合、コードを使用して、静的変数を実行している場合は、静的キーワードの全てが、再度の均一な実装を特定のクラスである、それはユーザーが指定した値のカバレッジ前の準備段階で設定した初期値を使用しますstatic代码块,那么在初始化阶段,JVM就会执行static代码块中定义的所有操作


作成されたオブジェクト:

典型的にのみnewkeywordされたオブジェクト(クローンデシリアライゼーション)を作成し、仮想マシン内の一方、例えば、オブジェクトを作成するステップ 

①と、新しい命令に仮想の機会。符号に対して標的クラスの定数プール、およびクラスは、このシンボルによって表されるかどうかを確認するための基準でこのコマンドは、ロードされ解析され、初期化されているかどうかを確認する最初のパラメータ。ノーと仮定。これは、適切な実行する必要があります 类载入过程


後でチェック中②クラスローディング。次の新入生は、仮想マシンのメモリ割り当てを対象とします。オブジェクトに必要なメモリサイズは、クラスのロード後に決定します。タスクオブジェクトのためのスペースの割り当てに相当します 一块确定大小的内存从Java堆划分出来

  ②.①オブジェクトを作成するプロセスは、それがまた、あるスレッドの安全性の問題を考慮する必要があり、実際に非スレッドセーフな処理です。可能なターゲットは、ポインタ、オブジェクトB及びメモリの元の割り当てへのポインタを使用して、同じ時間を変更するためのメモリではなく、十分な時間を割り当てることです。この問題を解決するには、次のとおりです。 

  スキーム、同期を割り当てられたメモリ空間の動作 - 実際に仮想マシンの故障の再試行の方法によって結合CASアトミック更新操作を保証します。

  スキームIIは、メモリ割り当て動作が異なる空間分割スレッドに従って行われます。つまり、Javaで事前に割り当てられたヒープメモリの小片各スレッドです。ローカルスレッド割り当てキャッシュ(TLAB)として知られています。それはTLABにどのスレッドを割り当てたときにメモリを割り当てるために、どのスレッド、ちょうどTLABが新しいTLABを実行し、割り当てていた、唯一のロックを同期する必要があります。-XXてTLABを使用して仮想マシン、:+/-パラメータを設定するUseTLAB。


割り当てられたメモリ③後。両方に割り当てられた仮想マシンのメモリ空間初始化为零值(不包括对象头)、TLABを仮定すると、このプロセスが場合TLAB分布前進させるように働くことができ、このステップは、現場で、そのオブジェクトのインスタンスを確実にしますJava代码中能够不赋初始值就能直接使用,程序能訪问到这些字段的数据类型所相应的零值


④次の仮想機密DUI 对象进行必要的设置このオブジェクトは口径のメタデータ情報クラス、オブジェクトのハッシュコード、情報の目的GC世代の年齢を見つける方法を、クラスのインスタンスであるかのような:、。この情報は、オブジェクトの存在のヘッダ情報に格納されています。仮想マシンの異なる実行状態によります。偏ったロックかどうかなど、オブジェクトが異なるヘッド配置を持つことになります。 


上記作業の完了後に从虚拟机角度来看,一个新的对象已经产生了、しかし観点からJavaプログラム、オブジェクトがまだ始まったばかり- (INIT)メソッドが実行されていません。すべてのフィールドは、一般的に、またゼロで、そう。执行new命令后。会接着执行init方法。把对象依照程序猿的意愿进行初始化,这样一个真正可用的对象才算全然产生出来。 


メモリレイアウトオブジェクト:

ホットスポットVMでは、オブジェクトは3つの領域に分割することができるメモリ・レイアウトに記憶されています。

  • オブジェクトヘッダ(ヘッダ)
  • データの例(インスタンスデータ)
  • アライメントパディング(パディング)

オブジェクトヘッドのHotSpot仮想マシンは、次の2つの情報で構成されています。

そのようなハッシュコード(ハッシュコード)などのランタイム・データ・オブジェクト自体を格納するための第一の部分、GC世代年齢ロック状態フラグスレッドは、スレッドIDバイアス、バイアスのタイムスタンプは、このデータ部分はマークと呼ばれ、ロックを保持していますWordの。  

オブジェクトヘッダポインタ型の別の部分、すなわち、そのクラスのオブジェクトへのポインタは、メタデータであり、仮想マシンがオブジェクト・クラスのインスタンスであるポインタによって決定されます。

データの例:有意情報オブジェクトは、実際のコンテンツの様々なタイプのプログラムコードフィールドに定義されて格納されています。

アライメント充填:必ずしも存在していないアライメントパディングを、それが唯一のプレースホルダでの役割を果たしている、特別な意味はありません。


アクセスオブジェクト場所:

オブジェクトを使用してJavaプログラムは、スタック上の特定の基準データによってヒープ上のオブジェクトを操作する必要がある場合。

現在主流の方法は、使用するアクセス権を持っている句柄直接指针两种

  • 次いで、ハンドルアクセスした場合、Javaヒープは、ハンドルのメモリセルに分割され、ハンドルは、オブジェクトの参照アドレスに格納され、ハンドルは、各データ・タイプのデータ・オブジェクト・インスタンスの特定のアドレス情報が含まれています。図示のように:


  • ダイレクトアクセスポインタは、Javaヒープ・レイアウト・オブジェクトは、データを配置する方法についてのアクセス情報のタイプを考慮しなければならない場合に示されるように、それが直接、ターゲットアドレス参照に格納されています。



おすすめ

転載: juejin.im/post/5d5511475188257761189dca