对象通过new,反射,clone等方式创建完毕后被存储到堆中,那么对象是以什么样的方式存储在堆中的?
对象的内存布局
对象在堆内存的内存布局主要有三部分,即对象头,实例数据,对其填充
对象头
对象头主要包含两部分的内容,一个叫运行时元数据(mark word),一个叫类型指针
- 1.运行时元数据:
- 哈希值(hashcode):对象在堆空间中都有一个首地址值,栈空间的引用根据这个地址指向堆中的对象,这就是哈希值起的作用
- GC分代年龄:对象首先是在Eden中创建的,在经过多次GC后,如果没有被进行回收,就会在survivor中来回移动,其对应的年龄计数器会发生变化,达到阈值后会进入养老区
- 锁状态标志,在同步中判断该对象是否是锁
- 线程持有的锁
- 线程偏向ID
- 偏向时间戳
- 2.类型指针,指向元数据区的代表当前类的class对象,确定该对象所属的类型
实例数据(Instance Data)
它是对象真正存储的有效信息,包括程序代码中定义的各种字段类型(包括从父类继承下来的和自己本身拥有的字段),注意这里有一些规则:相同宽度的字段总是被分配在一起,父类中定义的变量会出现在子类之前,因为父类的加载是优先于子类加载的
对齐填充
没有特殊含义,仅仅起到占位符的作用