我々は、単一の単純なJavaオブジェクトのサイズは、Javaはメモリレイアウトにオブジェクトを単一のメモリを共有する計算に説明しました。そして、この記事では、Javaの主な計算量は、共有メモリのサイズをオブジェクト説明することで、私たちは、複雑なオブジェクトと呼ばれる複合オブジェクトを継承します
継承オブジェクト
親{クラス 保護のint X; // 4バイト。 INT yを保護; // 4バイト 保護ブールフラグ; // 1バイト } クラス親子延び{ プライベートint型のZ; // 4バイト } publicクラスExtendsObjectSizer { 静的な無効メインパブリック(文字列[]引数){ するSystem.out.println( "継承オブジェクトのサイズは、" + ObjectSizeFetcher.sizeOf(新しい子( ))+ " バイト"); } }
次に、以下のコマンドを実行し、再パッケージ:
圧縮オンにされていない##ポインタ
のJava -XX:-UseCompressedOops -javaagent:ObjectSizeFetcherAgent-1.0-SNAPSHOT.jarにcom.twq.ExtendsObjectSizer
次のように得られた結果は以下の通りでした。
見ることができnew Child()
、その後40のバイトは、それが来るかで、メモリサイズは40バイトですか?私たちは見て:
16 + 40バイト=(4 + 4 + 7 + 1)+ 7 + 4
##オープンポインター圧縮 のjava -XX:+ UseCompressedOops -javaagent:ObjectSizeFetcherAgent -1.0-SNAPSHOT.jarにcom.twq.ExtendsObjectSizer
次のように得られた結果は以下の通りでした。
見ることができnew Child()
、その後32のバイトは、それが来るかで、メモリサイズは32バイトですか?私たちは見て:
32バイト= 12 + 4 + 4 + 4 + 7 + 1
要約:オブジェクトは1つのオブジェクトのみヘッドを継承し、オブジェクトは、共有メモリのサイズは、4つの部分から構成され継承します。
- オブジェクトヘッダ
- 父は、共有メモリのサイズを属性、8の倍数にサプリメントを整列する必要があります
- 子プロパティには、メモリサイズによって占められます
- サプリメントを揃え
複合オブジェクト
次は、次のコードを見て、メモリサイズを共有し、複雑なオブジェクトを見て:
{Employeeクラス プライベートint型の年齢; // 4つのバイト プライベート高いダブル; // 8バイト } クラス部門の{ プライベートINT NUM; // 4バイト のプライベート従業[] =新しい新しい従業員の従業員[3]; 公共部門の() { (INT I = 0; Iはemployees.lengthを<; I ++の)のために{ 社員[I]は、従業員を=新しい新しい(); } } } publicクラスCompositeObjectSizer { パブリック静的無効メイン(文字列[] args){IllegalAccessExceptionがスロー のSystem.outを.println( "化合物メモリサイズは:" + ObjectSizeFetcher.sizeOf(新しい部門( ))+ " バイト"); のSystem.out.println( "目的化合物の合計メモリサイズは" + ObjectSizeFetcher.fullSizeOf(新しい部門())+ "バイト"); } }
次に、以下のコマンドを実行し、再パッケージ:
次のように得られた結果は以下の通りでした。
複合オブジェクトは、メモリのサイズであることがわかります32字节 = 对象头16字节 + num属性4字节 + employees引用类型的大小8字节 + 对齐补充4字节
これは、部門に直接オブジェクト・スペースの現在のサイズを計算し、この配列のサイズは含まれていない唯一の32バイトemployees
の全Employee
合成にメモリサイズ、オブジェクトの合計サイズを176字节
、配列のサイズが含まれemployees
、すべてのEmployee
メモリサイズを、そして再帰計算は、現在のオブジェクト・スペースの合計サイズです。
アライメントパディングが各オブジェクト単位で行われ、以下の図が明らかに見ることは容易である:対象物によって占有再帰的演算メモリときことに留意すべきです。
同図によれば、我々は、手動で新しい部門()は、3つの部分に分け、合計メモリサイズを計算します。
- オブジェクト自体の例部門サイズは16 + 4 + 8 + 4 = 32バイト
- 従業Arrayオブジェクトサイズ:24×3 + 8 = 48のバイト
- 3従業員オブジェクトのサイズがある:3 *(16 + 4 + 4 + 8)= 96バイト
そう合計メモリサイズは、32 + 48 + 96 = 176のバイト
私たちは、サイズの複合オブジェクトポインタメモリ圧縮機能のターンを見てみましょう、私たちは、次のコマンドを実行します。
##オープンポインター圧縮 のjava -XX:+ UseCompressedOops -javaagent:ObjectSizeFetcherAgent -1.0-SNAPSHOT.jarにcom.twq.CompositeObjectSizer
次のように得られた結果は以下の通りでした。
複合オブジェクトは、メモリのサイズであることがわかります24字节 = 对象头12字节 + num属性4字节 + employees引用类型的大小4字节 + 对齐补充4字节
ポインタ圧縮の場合がオンされた以下に示すように、目的化合物の部門の合計サイズは、128バイトです。
同図によれば、我々は、手動で新しい部門()は、3つの部分に分け、合計メモリサイズを計算します。
- オブジェクト自体の例部門サイズは12 + 4 + 4 + 4 = 24バイト
- 従業Arrayオブジェクトのサイズ:16 * 3 + 4 + 4 = 32のバイト
- 3従業員オブジェクトのサイズがある:3 *(12 + 4 + 8)は、72バイト=
そう合計メモリサイズは、24 + 32 + 72 = 126のバイト
配列リスト
ここでは元のArrayListの一部は以下のとおりです。
パブリック抽象クラスAbstractList <E>拡張AbstractCollection <E>実装一覧<E> { 保護された過渡のint modCount = 0; } publicクラスのArrayList <E>はAbstractList <E>は延び 実装リスト<E>、ランダム・、Cloneableを、java.io.Serializableの { プライベート静的最終長いのserialVersionUID = 8683452581122892189L。 / ** *初期容量をデフォルト。 * / プライベート静的最終int型のDEFAULT_CAPACITY = 10; / ** *空のインスタンスに使用する空の配列のインスタンスを共有しました。 * / プライベート静的最終的なオブジェクト[] EMPTY_ELEMENTDATA = {}; プライベート静的最終的なオブジェクト[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 一時オブジェクト[]からelementData。//入れ子になったクラスへのアクセスを簡単にするために非プライベート / ** *のArrayListのサイズ(それが含まれている要素の数)。 * / プライベートint型のサイズ。 }
クラスに属する静的変数は、グローバル・データ・セグメントに格納され、インスタンスに属しません。共通の変数はJavaオブジェクト・スペースの計算に含まれていた、int型のサイズ、[]オブジェクトのストレージアレイ要素、int型のmodCountの親クラスがあります。したがって:
- 64ビットオペレーティングシステムでは、及び前提ポインタ圧縮をオンにしない、
new ArrayList<Integer>()
次のようにメモリサイズは:親オブジェクトヘッダ16バイト+ 4バイトのサイズクラス属性modCount + 4バイト+補助アライメントサブクラスオブジェクト[]参照型8バイトINT +サブクラス型アライメント属性のサイズは4バイト+ 4バイト= 40バイトが追加 - 64ビットオペレーティングシステムで、及び前提ポインタ圧縮をオンにし、
new ArrayList<Integer>()
次のようにメモリサイズは:目標親ヘッド12バイト+ 4バイト+ size属性modCountが4バイトアラインメント+サブクラスオブジェクト[]参照タイプを追加4バイト+ 4バイトアライメント=加え32バイトの4バイトINT +サブクラス型属性サイズ