作为一名Java程序员,我们在日常工作中使用这款面向对象的编程语言时,做的最频繁的操作大概就是去创建一个个的对象了。对象的创建方式虽然有很多,可以通过new、反射、clone、反序列化等不同方式来创建,但最终使用时对象都要被放到内存中,那么你知道在内存中的java对象是由哪些部分组成、又是怎么存储的吗?
本文将基于代码进行实例测试,详细探讨对象在内存中的组成结构。全文目录结构如下:
1、对象内存结构概述
2、JOL工具简介
3、对象头
4、实例数据
5、对齐填充字节
6、总结
文中代码基于JDK1.8.0_,64-BitHotSpot运行
1、对象内存结构概述在介绍对象在内存中的组成结构前,我们先简要回顾一个对象的创建过程:
1、jvm将对象所在的class文件加载到方法区中
2、jvm读取main方法入口,将main方法入栈,执行创建对象代码
3、在main方法的栈内存中分配对象的引用,在堆中分配内存放入创建的对象,并将栈中的引用指向堆中的对象
所以当对象在实例化完成之后,是被存放在堆内存中的,这里的对象由3部分组成,如下图所示:
对各个组成部分的功能简要进行说明:
对象头:对象头存储的是对象在运行时状态的相关信息、指向该对象所属类的元数据的指针,如果对象是数组对象那么还会额外存储对象的数组长度
实例数据:实例数据存储的是对象的真正有效数据,也就是各个属性字段的值,如果在拥有父类的情况下,还会包含父类的字段。字段的存储顺序会受到数据类型长度、以及虚拟机的分配策略的影响
对齐填充字节:在java对象中,需要对齐填充字节的原因是,64位的jvm中对象的大小被要求向8字节对齐,因此当对象的长度不足8字节的整数倍时,需要在对象中进行填充操作。注意图中对齐填充部分使用了虚线,这是因为填充字节并不是固定存在的部分,这点在后面计算对象大小时具体进行说明
2、JOL工具简介在具体开始研究对象的内存结构之前,先介绍一下我们要用到的工具,openjdk