对象创建过程

对象创建过程

碰到关键字new指令时,Java对象创建过程便开始,过程如下:

类加载检查
  • 检查该new指令的参数是否能在常量池中定位到一个类的符号引用。

  • 检查该类符号引用代表的类是否已被加载、解析和初始化过。

为对象分配内存(存在线程安全,需要重新做了解)
  • 虚拟机将为对象分配内存,即把一块确定大小的内存从堆中划分出来。(对象所需内存大小在类加载完成后便可以完全确定)

    内存分配方式

    a. 指针碰撞:java堆内存绝对规整,采用指针碰撞,分配形式,已使用内存在一边,未使用内存放一边,中间放一个作为分界点的指示器。

    内存分配指针碰撞

    b. 空闲列表:java对内存不规整,采用空闲列表。分配形式,虚拟机维护着一个记录可用内存块的列表,在分配时从列表中找到一块足够大的空间划分给对象实例,并更新列表记录。

    分配方式取决于java堆内存是否规整,而堆内存是否规整取决于所采用的垃圾回收器是否带有压缩整理功能。

将内存空间初始化为零值
  • 内存分配完成后,虚拟机需要将分配到的内存空间初始化为零(成员变量默认值,不包括对象头)
对对象进行必要的设置
  • 设置这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的hash码、对象的GC分代年龄等信息,这些信息存放在对象头中。

以上虚拟机角度对象初始化完毕,从开发角度,创建才刚开始,要进行我们的一系列初始化过程。

对象的内存布局

Java对象是如何存储在内存中的:对象头区、实例数据区、对齐填充区。

对象内存分布

对象头
  • 对象自身运行时数据:hash码、GC分代年龄、锁状态标志、线程持有的锁等。

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

    注意:如果对象是数组,对象头还会有一块用于记录数组长度的数据(从数组元数据无法确定数组的大小)。

实例数据
  • 存储对象真正有效的信息,即代码中定义的字段内容。
对齐填充
  • 存储的是占位符

    因为对象的大小必须是8字节的整数倍,并且因为HotSpot VM的要求对象起始地址必须是8字节的整数倍,且对象头部分正好是8字节的倍数,因此,当对象实例数据部分没有对齐时(即对象的大小不是8字节的整数倍),就需要通过对齐填充来补全。


对象创建过程
http://www.muzili.ren/2022/06/11/对象创建过程和内存分布/
作者
jievhaha
发布于
2022年6月11日
许可协议