Object object = new Object();
其中Object类模板在方法区 object引用在栈区 new Object()对象在堆区。
对象在堆内存中的布局
在hotspot虚拟机中,对象在堆内存中的布局分为三部分 :对象头(header)、实例数据(Instance Data)、对其填充(padding 保证8字节的倍数)
对象头
对象头分为对象标记 mark word和类元信息(类型指针)
在openJdk中对象头分为对象标记(markoop)和类元信息(klassoop),类元信息存储的是指向该对象类元数据klass的地址。
对象标记(mark word): 对象标记中持有哈希码、GC标记、GC次数、同步锁标记、偏向锁持有者
在64位的系统中 mark word 占用 8字节 类型指针占用 8字节 一共16字节
定义一个Customer类 属性有 id name acct等那么我们Customer customer = new Customer()定义一个对象后在内存中的分布如图
实例数据
存放类的属性数据信息,包括父类的属性信息
对齐填充
虚拟机要求对象起始地址必须是8字节的整数倍,填充数据不是必须存在,仅仅是为了字节这部分内存按8字节补充对齐。
可以通过java jol工具分析java对象的内存结构
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.9</version>
</dependency>
public class JOLDemo {
public static void main(String[] args) {
System.out.println(ClassLayout.parseInstance(new Object()).toPrintable());
}
}
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
新建一个带有属性的类对象打印后如下图所示