深入理解Java虚拟机之对象探秘

本文深入讲解Java对象创建过程,包括类加载、内存分配、对象初始化等关键步骤,探讨指针碰撞与空闲列表两种内存分配方式,以及并发场景下的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对象创建

熟悉了Java的内存区域,今天我们来了解下对象的创建:new Object()

类加载

当虚拟机遇到一个new指令的时候,首先去检查这个指令的参数能否在常量池中定位到一个类的符合引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化,如果没有,需要先执行类加载过程。

内存分配

在类加载检查通过后,接下来虚拟机将在堆上为对象分配内存,有如下两种分配方式:

  • 指针碰撞(Bump the Pointer)
    如果Java堆中内存是绝对规整的,已分配内存与空闲空间分割开来,分配内存时只需将指针向空闲空间移动一段与对象大小相等的距离。

  • 空闲列表(Free List)
    如果Java堆中的内存并不是规整的,就无法使用指针碰撞,虚拟机需要维护一个空闲内存列表,分配内存时从这个列表中找到一块足够大的空间划分给对象实例,并更新列表记录。

如何防止并发分配

由于对象创建在虚拟机上是非常频繁的行为,可能会出现同一块内存空间分配给了不同的对象。解决这个问题,有以下两种方案:

  • 采用CAS加失败重试方式

  • 将分配的动作按照线程划分在不同的空间之中进行,即为每个线程在堆中预先分配一段内存空间,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),分配内存时在TLAB上分配,只有当TLAB用完并分配新的TLAB时,才需要同步锁定。可以通过-XX:+/-UseTLAB来设置虚拟机是否使用TLAB。

对象初始化

内存分配完成后,虚拟机需要将分配的内存空间都初始化为0值(不包括对象头)。然后设置对象头信息,如对象的哈希码、对象的GC分代年龄、锁状态标志等。设置完对象头后,会接着执行init方法,按照程序员的意愿进行初始化,这样一个对象就被new出来了。

如果读完觉得有收获的话,欢迎点赞、关注、加公众号【Java在线】,查阅更多精彩历史!!!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值