Java普通对象内存布局
一个普通对象,在内存中占多大?
普通对象在内存中主要分三部分组成
- 对象头:对象头分markwork和classpointer组成,markword主要存放标记位,classpointer用来存放类型指针
- 对象数据:这里主要存放的是指针的地址
- 对齐填充:hotspot规定,对象的起始地址占用内存大小必须为8的整倍数,不足的话,要补齐
这个内存占用大小还跟机器的位数(32或64位)、是否开启指针压缩(-XX:-UseCompressedOops)有关,下面举例:
- 引入jar包
JOL,全称Java Object Layout,Java对象布局
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.16</version>
</dependency>
- 测试代码(开启指针压缩)
public static class TTT {
}
public static void main(String[] args) {
TTT ttt = new TTT();
String str = ClassLayout.parseInstance(ttt).toPrintable();
System.out.println(str);
}
测试结果:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0xf800c147
12 4 java.lang.String TTT.a null
Instance size: 16 bytes
mark:占用了8个字节,class指针占用了4个,String实例指针占用了4个,没有对齐,一共占用了16个字节
- 测试代码(关闭指针压缩)
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 8 (object header: class) 0x00000001260650e0
16 8 java.lang.String TTT.a null
Instance size: 24 bytes
mark:占用了8个,class指针占用了8个,String实例指针占用了8个,没有对齐,一共24个字节
- 总结:
32位不可以开启指针压缩,64位的才可以开启指针压缩,class pointer开启指针压缩占用4个字节,不开启,则占用8个字节,在64位系统中,默认是开启指针压缩的。
问:new Object()
占用了多大内存?
答:16个字节(开不开启指针压缩都一样)
问:对象头都包含什么?mark word里都记录了什么信息?
答:对象头包含了mark word和class pointer,mark word里记录了对象锁的信息,hashcode以及GC信息