对象在内存中的存储布局可以分为3个部分:Header、Instance Data、Padding
对象头由以下几部分组成:Mark Word、Klass Pointer 、数组指针
Mark Word
8b
存储对象的HashCode 分代年龄 锁标志位信息 线程持有的锁 偏向id 偏向时间戳等
HotSpot 虚拟机对象头Mark Word
存储内容 |
标志位 |
状态 |
对象hashcode 分代年龄 |
01 |
无锁 |
偏向线程id 偏向时间戳 |
01 |
偏向锁 |
指向锁记录的指针 |
00 |
轻量级锁定 |
指向重量级锁的指针 |
10 |
重量级锁定 |
空不需要记录 |
11 |
gc标记 |
KlassPoint 4b
数组长度 4b(只有数组对象才有)
Instance Data(实例数据)
对象里的各种字段内容
Padding (对齐填充)
HotSpot要求对象总长度是8字节的整数倍 ,如果Head+Instance Data不是8字节的整数倍,会通过Padding来补全
对象的大小和指针压缩
1 2 3 4 5 6
| 对象的大小可以引入jol包查看 <dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.16</version> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import org.openjdk.jol.info.ClassLayout; public class Test {
public static void main(String[] args) { ClassLayout classLayout = ClassLayout.parseInstance(new Object()); System.out.println(classLayout.toPrintable()); System.out.println();
ClassLayout classLayout1 = ClassLayout.parseInstance(new int[]{}); System.out.println(classLayout1.toPrintable()); System.out.println();
ClassLayout classLayout2 = ClassLayout.parseInstance(new A()); System.out.println(classLayout2.toPrintable()); System.out.println(); }
public static class A{ int id; String name; byte b; Object o; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| java.lang.Object object internals: OFF SZ TYPE DESCRIPTION VALUE 0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0) 8 4 (object header: class) 0xf80001e5 12 4 (object alignment gap) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
[I object internals: OFF SZ TYPE DESCRIPTION VALUE 0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0) 8 4 (object header: class) 0xf800016d 12 4 (array length) 0 12 4 (alignment/padding gap) 16 0 int [I.<elements> N/A Instance size: 16 bytes Space losses: 4 bytes internal + 0 bytes external = 4 bytes total
Test$A object internals: OFF SZ TYPE DESCRIPTION VALUE 0 8 (object header: mark) 0x0000000000000005 (biasable; age: 0) 8 4 (object header: class) 0xf80102ea 12 4 int A.id 0 16 1 byte A.b 0 17 3 (alignment/padding gap) 20 4 java.lang.String A.name null 24 4 java.lang.Object A.o null 28 4 (object alignment gap) Instance size: 32 bytes Space losses: 3 bytes internal + 4 bytes external = 7 bytes total
|