对象内存布局详解
对象内存布局详解声明64bit虚拟机和32bit虚拟机,对象所占内存是不一样的:64位jvm中Mark Word占64bit;32位jvm中Mark Word占32bit。根据是否开启元数据类型指针:如果开启- klass占8字节;如果不开启(默认不开启)- klass占4个字节一、对象内存布局1. 对象布局介绍HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)
对象内存布局详解
声明
64bit虚拟机和32bit虚拟机,对象所占内存是不一样的:
64位jvm中Mark Word占64bit;
32位jvm中Mark Word占32bit。
根据是否开启元数据类型指针:
如果开启- klass占8字节;
如果不开启(默认不开启)- klass占4个字节.
手动设置开启指针压缩:-XX:+UseCompressedOops
一、对象内存布局
1. 对象布局介绍
HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。
1.1 对象头
• 对象头:比如 hash码,对象所属的年代,对象锁,锁状态标志,偏向锁(线程)ID,偏向时间, **数组长度(数组对象)**等。
1.1.1 对象头由两或三部分组成:
1.Mark Word
2.Klass pointer
3.数组长度(只有数组对象才有)
1.1.2 32bit的JVM对象头中的MarkWord存储
无锁状态的时候:只有调用了hashcode()才会生成hash码值。
对象头 - hashcode场景分析
偏向锁的hashcode存在哪呢?
– 推测可能在monitor中。
1.1.2 64bit的JVM对象头中的MarkWord存储
1.1.3 klass释义
对象通过klass这个地址值,到方法区找到元数据信息。
元数据指针:堆中的对象通过元数据指针(地址)找到方法区中的元数据信息。(Java对象在加载阶段,会创建一个java.lang.class类,可以通过反射的方式获取类的信息,类的信息存储在方法区,反射是通过元数据指针拿到信息的。)
1.1.4 为什么数组对象的对象头会多个数组长度
如果对象是数组类型,因为JVM虚拟机可以通过Java对象的元数据信息确定Java对象的大小,但是无法从数组的元数据来确认数组的大小,所以用一块来记录数组长度。
1.2 实例数据
• 实例数据:存放类的属性数据信息,包括父类的属性信息;
注意:包括父类的属性信息。
1.3 对齐填充
• 对齐填充:由于虚拟机要求 对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐;
1.3.1为什么必须是8个字节?
根据“计算机组成原理”,8个字节是计算机读取和存储的最佳实践。
2.对象的创建与OOP-Klass模型的关系
class Model
{
public static int a = 1;
public int b;
public Model(int b) {
this.b = b;
}
}
public static void main(String[] args) {
int c = 10;
Model modelA = new Model(2);
Model modelB = new Model(3);
}
方法区:类(元数据)信息、类变量(静态变量和常量)、方法信息
类的信息如:类名,类路径,类中方法,类中的属性等等;
方法信息:方法的名字,方法有多少个等等;
切记:方法信息只存有关方法的信息,不存方法里面具体内容。具体的内容是字节码执行引擎在执行每个方法的时候在Java虚拟机栈生成栈帧进行存储的。
堆:对象、成员变量
栈:局部变量
3.Oop-Klass模型于反射的关系
Java对象在加载阶段,会创建一个java.lang.class类,可以通过反射的方式获取类的信息,类的信息存储在方法区,反射是通过元数据指针拿到信息的。
结语
在了解对象头中的具体内容后,我们开始研究在并发场景下,对象头中的状态是如何变化的?
二、锁膨胀过程详解讲解
更多推荐
所有评论(0)