少し遅いかもしれませんが、次のとおりです。
配列は連続したブロックとして割り当てられます。サイズはクラスsun.misc.Unsafeを使用して導き出すことができます(いくつかの優れたチュートリアルはこちら)。これにより、生のメモリへのネイティブ アクセスが可能になります。たとえば、int
s の配列の割り当てサイズは次のとおりです (バイト単位)。
Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * length
hotspot-jvm の実装により、すべてのオブジェクトが 8 または 4 バイト (プラットフォームによって異なります: AMD64 または x86_32) に配置されるため、配列の実際のサイズは 8 または 4 バイトの倍数に増加します。
unsafe クラスを使用して、実際のデータを検査できます。
public static void main(String[] args) {
//Get the unsafe object.
Unsafe unsafe = null;
try {
Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (sun.misc.Unsafe) field.get(null);
} catch (Exception e) {
throw new AssertionError(e);
}
//define our array
int[] data = new int[]{0,1,2,3,4,5,6,7,8,9};
//calculate length (ignoring alignment)
int len = Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * data.length;
//Some output formatting
System.out.print(" 0| ");
for(int i = 0; i < len; i++){
//unsafe.getByte retrieves the byte in the data struct with offset i
//This is casted to a signed integer, so we mask it to get the actual value
String hex = Integer.toHexString(unsafe.getByte(data, i)&0xFF);
//force a length of 2
hex = "00".substring(hex.length()) + hex;
//Output formatting
System.out.print(hex);
System.out.print(" ");
if(i%4 == 3 && i != len -1){
System.out.println();
if(i < 9){
System.out.print(" ");
}
System.out.print((i+1) +"| ");
}
}
System.out.println();
}
結果は次のとおりです。
0| 01 00 00 00
4| 00 00 00 00
8| 32 02 8c f5
12| 08 00 00 00
16| 00 00 00 00
20| 01 00 00 00
24| 02 00 00 00
28| 03 00 00 00
32| 04 00 00 00
36| 05 00 00 00
40| 06 00 00 00
44| 07 00 00 00
したがって、整数はオフセット 16 から始まるリトル エンディアンで保存されていることがわかります。オフセット 12 ~ 16 の整数は、配列の長さです。0 ~ 12 のバイトは何らかのマジック ナンバーを構成していますが、それがどのように機能するかはよくわかりません。
ノート
JVM のプロパティを使用するコードを作成することはお勧めしません。移植性が非常に低く、更新の合間に破損する可能性があるためです。それにもかかわらず、配列が連続したブロックとして割り当てられていると安全に想定できると思います。