一个Java对象的存储构造。在Hotspot虚拟机中,对象在内存中的存储布局分为 3 块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)
Java 对象实例
Hotspt 采纳了 OOP-Klass 模型。 它是形容 java 对象实例的模型,可分为两局部:
OOP (Ordinary Object Pointer)指的是一般对象指针,它蕴含 MarkWord 和Klass 指针。MarkWord 用于存储以后对象运行时的一些状态数据;Klass 指针则指向 Klass,用来通知以后指针指向的对象是什么类型,即对象是应用哪个类创立进去的
之所以采纳这种一分为二的对象模型,是因为 hotspot jvm 的设计者不想让每个对象中都蕴含一个 virtual table (虚函数表), 所以把对象模型拆成 klass 和 oop,其中 oop 不蕴含任何虚函数,而 klass 含有虚函数表,能够进行method dispatch
- 对象头
HotSpot虚拟机的对象头包含两局部信息:
_mark:markOop
第一局部_mark:markOop,用于存储对象本身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标记、线程持有的锁、偏差线程ID、偏差工夫戳等。这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中别离为32bit和64bit,官网称“MarkWord”
_klass:klassOop
对象头的另外一部分是klass类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例
length
如果是数组对象的话,对象头还有一块示意数组长度的数据,大小是32bit,4个字节
- 对象理论数据
实例数据局部是对象真正存储的无效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类继承下来的,还是在子类中定义的,都须要记录起来。
对齐填充
第三局部对齐填充并不是必然存在的,也没有特地的含意,它仅仅起着占位符的作用。因为HotSpot VM的主动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说,就是对象的大小必须是8字节的整数倍。而对象头局部正好是8字节的倍数(1倍或者2倍),因而,当对象实例数据局部没有对齐时,就须要通过对齐填充来补全。
简略能够概括如下
晓得了这4个局部之后,咱们来验证一下底层。借助于第三方包 JOL = Java Object Layout java内存布局去看看。很简略的几行代码就能够看到内存布局的款式:
<dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.9</version></dependency>
public class JOLSampleDataModels { private static Object o; public static void main(String[] args) { o = new Object(); System.out.println(ClassLayout.parseInstance(o).toPrintable()); System.out.println("================== 加载锁之后 =================="); synchronized (o) { System.out.println(ClassLayout.parseInstance(o).toPrintable()); } }}
从输入后果看:
对象头蕴含了12个字节分为3行,其中前2行其实就是markword,第三行就是klass指针。值得注意的是在加锁前后输入从001变成了000。Markword用途:8字节(64bit)的头记录一些信息,锁就是批改了markword的内容8字节(64bit)的头记录一些信息,锁就是批改了markword的内容字节(64bit)的头记录一些信息。从001无锁状态,变成了00轻量级锁状态。
New出一个object对象,占用16个字节。对象头占用12字节,因为Object中没有额定的变量,所以instance = 0,思考要对象内存大小要被8字节整除,那么padding=4,最初new Object() 内存大小为16字节。
拓展
什么样的对象会进入老年代?很多场景例如对象太大了能够间接进入,然而这里想探讨的是为什么从Young GC的对象最多经验15次Young GC还存活就会进入Old区(年龄是能够调的,默认是15)。上图中hotspots的markword的图中,用了4个bit去示意分代年龄,那么能示意的最大范畴就是0-15。所以这也就是为什么设置新生代的年龄不能超过15,工作中能够通过-XX:MaxTenuringThreshold去调整,然而个别咱们不会动。
【欢送关注】:码农架构
专一于零碎架构、高可用、高性能、高并发类技术分享