Java 原始数组在内存中的布局
Java primitive array layout in memory
这是我想作为我的问题基础的两个示例(假设您在这里有 JOL
):
Layouter layout32Bits = new HotSpotLayouter(new X86_32_DataModel());
Layouter layout64BitsComp = new HotSpotLayouter(new X86_64_COOPS_DataModel());
以及一个使用这个的例子:
int [] ints = new int[10];
System.out.println(ClassLayout.parseInstance(ints, layout32Bits).toPrintable());
System.out.println(ClassLayout.parseInstance(ints, layout64BitsComp).toPrintable());
这是两个输出:
[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 09 00 00 00 (00001001 00000000 00000000 00000000) (9)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 10 1b 0c 1a (00010000 00011011 00001100 00011010) (437000976)
12 40 int [I.<elements> N/A
52 12 (loss due to the next object alignment)
Instance size: 64 bytes
Space losses: 0 bytes internal + 12 bytes external = 12 bytes total
[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 09 00 00 00 (00001001 00000000 00000000 00000000) (9)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 10 1b 0c 1a (00010000 00011011 00001100 00011010) (437000976)
12 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
16 40 int [I.<elements> N/A
56 8 (loss due to the next object alignment)
Instance size: 64 bytes
Space losses: 0 bytes internal + 8 bytes external = 8 bytes total
我主要是看懂了输出,不懂的是这些是什么:
12 bytes external and 8 bytes external
一般来说,对象是 8 bytes
对齐的,那么为什么需要添加比需要的 更多 的填充?
我知道一些奇怪的事情, and the second has to do with internal data, that needs to be hidden。
我也知道 this,但它似乎无关,因为它意味着 内部填充。
有人可以解释一下吗?
Instance size: 64 bytes
是针对当前 VM 配置计算的,但您明确指定不同(不兼容)Layouter
。
实际大小(用 Instrumentation.getObjectSize
计算)和预期大小(用 Layouter 计算)之间的差异将被视为 loss due to the next object alignment
。
这是我想作为我的问题基础的两个示例(假设您在这里有 JOL
):
Layouter layout32Bits = new HotSpotLayouter(new X86_32_DataModel());
Layouter layout64BitsComp = new HotSpotLayouter(new X86_64_COOPS_DataModel());
以及一个使用这个的例子:
int [] ints = new int[10];
System.out.println(ClassLayout.parseInstance(ints, layout32Bits).toPrintable());
System.out.println(ClassLayout.parseInstance(ints, layout64BitsComp).toPrintable());
这是两个输出:
[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 09 00 00 00 (00001001 00000000 00000000 00000000) (9)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 10 1b 0c 1a (00010000 00011011 00001100 00011010) (437000976)
12 40 int [I.<elements> N/A
52 12 (loss due to the next object alignment)
Instance size: 64 bytes
Space losses: 0 bytes internal + 12 bytes external = 12 bytes total
[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 09 00 00 00 (00001001 00000000 00000000 00000000) (9)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 10 1b 0c 1a (00010000 00011011 00001100 00011010) (437000976)
12 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
16 40 int [I.<elements> N/A
56 8 (loss due to the next object alignment)
Instance size: 64 bytes
Space losses: 0 bytes internal + 8 bytes external = 8 bytes total
我主要是看懂了输出,不懂的是这些是什么:
12 bytes external and 8 bytes external
一般来说,对象是 8 bytes
对齐的,那么为什么需要添加比需要的 更多 的填充?
我知道一些奇怪的事情,
我也知道 this,但它似乎无关,因为它意味着 内部填充。
有人可以解释一下吗?
Instance size: 64 bytes
是针对当前 VM 配置计算的,但您明确指定不同(不兼容)Layouter
。
实际大小(用 Instrumentation.getObjectSize
计算)和预期大小(用 Layouter 计算)之间的差异将被视为 loss due to the next object alignment
。