配列の長さはJVMのどこに保存されますか?
1. 概要
このクイックチュートリアルでは、HotSpotJVMが配列の長さを格納する方法と場所を確認します。
通常、ランタイムデータ領域のメモリレイアウトはJVM仕様の一部ではなく、実装者の裁量に任されています。 したがって、各JVM実装には、メモリ内のオブジェクトと配列をレイアウトするための異なる戦略がある場合があります。
このチュートリアルでは、特定のJVM実装であるHotSpotJVMに焦点を当てています。 また、JVMとHotSpotJVMの用語を同じ意味で使用する場合もあります。
2. 依存
JVM内の配列のメモリレイアウトを検査するために、Javaオブジェクトレイアウト( JOL )ツールを使用します。 したがって、jol-core依存関係を追加する必要があります。
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.10</version>
</dependency>
3. 配列の長さ
- IDハッシュコードまたはGC情報を格納するための1つのマークワード
- 一般的なクラスのメタデータを格納するための1つのクラスワード
- 配列の長さを表す4バイト
したがって、 JVMは、配列の長さをオブジェクトヘッダーに格納します。
配列のメモリレイアウトを調べて、これを確認しましょう。
int[] ints = new int[42];
System.out.println(ClassLayout.parseInstance(ints).toPrintable());
上に示したように、既存の配列インスタンスからメモリレイアウトを解析しています。 JVMがint[]をレイアウトする方法は次のとおりです。
[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1) # mark
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) # mark
8 4 (object header) 6d 01 00 f8 (01101101 00000001 00000000 11111000) (-134217363) #klass
12 4 (object header) 2a 00 00 00 (00101010 00000000 00000000 00000000) (42) # array length
16 168 int [I.<elements> N/A
Instance size: 184 bytes
前述のように、JVMは、markおよびklassワードの後のオブジェクトヘッダー内に配列の長さを格納します。 また、配列の長さは4バイトで格納されるため、32ビット整数の最大値を超えることはできません。
オブジェクトヘッダーの後に、JVMは実際の配列要素を格納します。 42個の整数の配列があるため、配列の合計サイズは168バイト(42に4を掛けたもの)になります。
4. 結論
この短いチュートリアルでは、JVMが配列の長さを格納する方法を確認しました。
いつものように、すべての例はGitHubでから入手できます。