对象在内存中的存储布局可以分为3个部分:Header、Instance Data、Padding

Header(对象头)

对象头由以下几部分组成:Mark Word、Klass Pointer 、数组指针

  1. Mark Word

    8b

    存储对象的HashCode 分代年龄 锁标志位信息 线程持有的锁 偏向id 偏向时间戳等

    ​ HotSpot 虚拟机对象头Mark Word

    存储内容 标志位 状态
    对象hashcode 分代年龄 01 无锁
    偏向线程id 偏向时间戳 01 偏向锁
    指向锁记录的指针 00 轻量级锁定
    指向重量级锁的指针 10 重量级锁定
    空不需要记录 11 gc标记
  2. KlassPoint 4b

  3. 数组长度 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