JAVA对象内存布局

JAVA对象内存布局

对象头:

  • markword:记录锁的信息、GC信息
  • 类型指针class pointer:记录对象属于哪个Class类型的

实例数据instance data:成员变量

对齐 padding:当整个对象的字节数不能被8整除时,补齐剩余字节。因为JDK读内存时按照内存宽度读取,被8整除读取速度较快

1
2
3
4
5
6
<!-- 工具:JOL=JAVA Object Layout -->
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.14</version>
</dependency>
1
2
3
4
public static void main(String[] args) {
Object o = new Object();
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
1
2
3
4
5
6
7
8
java.lang.Object object internals:
OFFSET(从什么位置开始) SIZE(往后的长度) TYPE DESCRIPTION(类型描述) VALUE
0 4 (object header)[markword] 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header)[markword] 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header)[class pointer] e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
12 4 (loss due to the next object alignment)[padding]
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
1
2
3
4
5
java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=267312128 -XX:MaxHeapSize=4276994048 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)

-XX:+UseCompressedClassPointers:默认开启类型指针class pointer压缩,8个字节压缩成4个字节

-XX:+UseCompressedOops:默认开启实例数据instance data压缩,比方说String类型占用8个字节,压缩成4个字节

数组的话会有一个数组长度length,占用4个字节。

类型 占用字节 占用位数
byte 1 8
short 2 16
int 4 32
long 8 64
float 4 32
double 8 64
char 2 16
boolean 1 8

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Data
public class Account {
private long id;
private String username;
private String password;

public static void main(String[] args) {
Object o1 = new Object();
System.out.println("空对象:" + ClassLayout.parseInstance(o1).toPrintable());
Object o2 = new Account();
System.out.println("带属性对象:" + ClassLayout.parseInstance(o2).toPrintable());
Object o3 = new int[1];
System.out.println("数组:" + ClassLayout.parseInstance(o3).toPrintable());
Object o4 = new ArrayList<>();
System.out.println("空List:" + ClassLayout.parseInstance(o4).toPrintable());
}
}

控制台输出:

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
31
32
33
34
35
36
37
38
39
40
41
42
空对象:java.lang.Object object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
12 4 (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

带属性对象:cn.happyloves.example.dto.Account object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 05 00 00 00 (00000101 00000000 00000000 00000000) (5)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 54 c3 00 f8 (01010100 11000011 00000000 11111000) (-134167724)
12 4 java.lang.String Account.username null
16 8 long Account.id 0
24 4 java.lang.String Account.password null
28 4 (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

数组:[I object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 6d 01 00 f8 (01101101 00000001 00000000 11111000) (-134217363)
12 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
16 4 int [I.<elements> N/A
20 4 (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

空List:java.util.ArrayList object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 05 00 00 00 (00000101 00000000 00000000 00000000) (5)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 7f 2f 00 f8 (01111111 00101111 00000000 11111000) (-134205569)
12 4 int AbstractList.modCount 0
16 4 int ArrayList.size 0
20 4 java.lang.Object[] ArrayList.elementData []
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

JAVA对象内存布局
https://happyloves.cn/20220707/9e1b7d3d81ac.html
作者
赵小胖
发布于
2022年7月7日
许可协议