「五分一日、JVM楽しい」:オブジェクトのメモリレイアウト

概要

オブジェクトの状況に応じてオブジェクトが非オブジェクトの配列である場合、2つのケースに分けることができるときにオブジェクトヘッダ、インスタンスデータ、メモリの世界のアライメントパディング第三、および付きオブジェクトヘッダ内の複数のオブジェクトの配列これは、長さの部分にオブジェクトの配列を記載しています

画像-20190823221858767

オブジェクトヘッダ

オブジェクトヘッダが2つの部分に分割される、**「マークワード」と呼ばれる最初の部分は、取得するオブジェクトタイプの第二の部分であるオブジェクトが配列は、さらに、アレイのデータ・レコードの長さを備えている場合、タイプ**ポインタ。

異なるオペレーティング・システムでは、異なるメモリ領域は、32ビットシステムでは32ビットMarkWord(すなわち4バイト)が占める空間を占有します。コラボレーション・スペース32ビットとしてポインタと配列の長さのデータを入力します。

64ビットオペレーティングシステム、MarkWord 64ビットが占める空間の場合には、ポインタ圧縮の種類は、(CompressedOOPs)のポインタになっていない残りの32ビット(4バイト)、オープンポインタ圧縮の場合には、64ビット(8バイト)であります

画像-20190823225703812

マーク・ワード

この部分は、に格納されているオブジェクト自体ランタイムデータ、一緒に固定されていないコンテンツのデータ構造には、オブジェクトの状態に応じて、独自のストレージ・スペースを再利用します

画像-20190823230559543

この断片は、以下の5つのオブジェクトの状態を表すmarkOop.hppファイルから抽出しました。

バイアスされたロックフラグ 状態
01 0 いいえロックません
01 1 バイアスされたロック
00 ノー 軽量ロック
10 ノー ヘビーロック
11 ノー GCマーク

その後、我々はMarkWordの構造を見に行くされています。

画像-20190823231212050

ここでは、唯一の初期化は、非バイアスロックロック状態構造を定義することを見ることができる(上半分がCOOPs-ポインタ圧縮構造を開き、下半分が圧縮構造体へのポインタを開放されていません)

ロックが軽量である場合、ヘビーロックオブジェクトポインタは、JVMの指示に従って、ポインタ64依然として、下位2ビットが0であると仮定し、この時間を記録し、バイアスされたロックで、レコードが取得ロックバイアスされたとき64スレッドポインタ。

画像-20190823231522289

より多くのコンテンツは、我々はここに拡大していないだろう、とのフィードバックに基づいて、私は後ろにロックを話すために、単一の進化のパスに並列プログラミングを開きます。

ポインタ型

このことは、時々 、オブジェクトが属するかどうかを決定するために使用されるクラスのどのインスタンスが、それはまた、より少ない時間を使用し、これは、ポインタのこの種の使用に関するのHotSpot JVMなどの異なる仮想マシン(に基づく選択アルゴリズムを実現するためにオブジェクトを配置するために行われるべきですオブジェクトタイプのデータを取得します)

データの例

実際のデータの例は、プログラムコードに格納された有効なオブジェクト情報であるが、定義された様々なタイプのフィールドの内容、フィールドの内容、本明細書の親クラスで定義された彼のフィールドを含む現在のクラスのフィールドだけでなく、を含みます。

このセクションのストレージ・ルールは、仮想マシン割り当てストラテジパラメータに従い、フィールドは、HotSpotのJVMデフォルト割り当て方式であるロング/ダブル、INT、ショート/チャー、バイト/ブーリアン、おっと(共通オブジェクト・ポインタ、通常のオブジェクトのJavaソースコードの順序を定義しますポインタ)も言うことは私たちの次のセクションで参照、ポインタ圧縮として理解することができます。

これは、親クラスで定義された変数は、サブクラスの前に現れることに留意すべきであるが、我々はCompactFiledsパラメータでtrueに設定することができ、スペース小さい親の大きな変数にサブカテゴリー変数。

画像-20190824120847519

アライメントパディング

所定のホットスポットJVMので、必ずしも存在しない場合、このセクションは、8バイトの整数倍でなければならないオブジェクトのサイズ、同様の機能をにC / C ++で呼び出されるメモリ位置合わせ、メモリ空間はバイトに応じて分割されます、変数の任意の型へのアクセスは、理論的には任意のアドレスから開始することができるようですが、現実には、一定のルールに従って各種のデータを必要とする、変数の特定の種類にアクセスするとき、特定のメモリアドレスへのアクセスであることが多いですそれらはむしろ、整列された放電後順次ものよりも、空間に配置されています。

メモリ配置は、二つの規則に従います。

  • そのデータ型はスペースの量の整数倍でなければならない第一の部材開始アドレスが0であると仮定し、各メンバーの開始アドレス(startPos)

  • 構造体の最終的なサイズは、最大部材の寸法の割合で、そのメンバー(基礎となるデータ型メンバー)の倍数でなければなりません。

ここでは、64ビットシステム(ポインタ圧縮が開かない)に、多くの占める8バイトデータ型のオブジェクトがあるので、所定のオブジェクトのJVMのサイズは、8バイトの整数倍でなければならない理由を理解することは困難ではありません。しかし、その後、我々は、不満8バイト部分を補完するために8の整数倍を一緒に考え出すために、役割を果たしているとパディング、また、4バイトのデータ型のいくつかあります。

画像-20190824121114907

いいえ公共ありません

おすすめ

転載: juejin.im/post/5d76ef776fb9a06b0f2409ee