JVM内的对象创建过程&对象头&对象的组成详解

对象创建过程

当new一个对象的时候,首先会检查这个对象是否已经被类加载器加载,没有加载则按照当前的类加载器去加载(全盘委托机制)有加载或加载完毕后为其分配内存空间。

分配内存空间

在类加载检查通过后,接下来虚拟机将为新生对象分配内存。
划分内存的方法:

  • 指针碰撞 :(默认使用指针碰撞)
    如果java堆中的内存是规范的,那么一边是使用过的内存一边是空的内存,那么会在中间加一个指针作为分界点的指示器,分配的内存就是把指针向空闲的位置 挪一段与对象大小相同的位置即可
  • 空闲列表
    如果Java堆中的内存并不是规整的,就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例, 并更新列表上的记录

初始化

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头)这一步叫初始化

设置对象头

然后就要设置对象头虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头Object Header之中。

执行<"init"> 方法

就是为属性赋值,赋上程序员赋的那个值,并不是初始化中的零赋值

对象的组成部分

对象是由三部分组成:对象头(Header)、 实例数据(Instance Data)和对齐填充(Padding)。

对象头

对象头内分为三部分

1.Mark Word

Mark Word在32位JVM中的长度是4个字节,在64位JVM中长度是8个字节
用于存储对象自身的运行时数据, 如哈 希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时 间戳等


32位的mark word图

2.Klass Pointer类型指针(开启压缩占4个字节,未开启占8个字节)

对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

3.数组长度

4个字节,只有数组对象有

示例数据

对象的实例数据就是在代码中能看到的属性和他们的值。

对齐填充

因为JVM要求java的对象占的内存大小应该是8个字节的倍数,所以后面有几个字节用于把对象的大小补齐至8个字节的倍数

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容