侧边栏壁纸
博主头像
月伴飞鱼 博主等级

行动起来,活在当下

  • 累计撰写 39 篇文章
  • 累计创建 25 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录
JVM

JVM是如何创建对象的?

月伴飞鱼
2025-03-11 / 0 评论 / 1 点赞 / 3 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

JVM 创建对象的过程

JVM 在创建对象时主要经历以下步骤:

1. 检查类的加载状态

  • JVM 会检查指令中引用的类是否已被加载、解析和初始化。

  • 如果类未被加载,则触发类加载过程,完成加载、链接和初始化。

2. 分配内存

JVM 会在堆中为对象分配内存空间。

分配方式取决于堆的状态:

  1. 指针碰撞(Bump-the-pointer):

    • 适用于堆内存是规整的情况(所有已分配和未分配内存分布在两侧)。

    • JVM 使用一个指针记录当前可用的内存地址,分配时将指针向前移动分配内存。

    • 高效,但需要堆经过垃圾收集后保持规整。

  2. 空闲列表(Free-list):

    • 适用于堆内存存在碎片的情况(内存分布不连续)。

    • JVM 维护一个空闲列表,记录所有未分配内存块。分配时遍历空闲列表,找到足够大的块。

并发内存分配的安全性:

  • CAS + 失败重试:利用原子操作确保多线程分配内存的安全性。

  • Thread Local Allocation Buffer (TLAB):为每个线程分配一个私有内存区域,用于分配小对象,减少锁竞争。

3. 内存初始化

  • JVM 将分配到的内存空间初始化为零值,确保对象字段具有默认值:

    • 基本类型:int0booleanfalse 等。

    • 引用类型:初始化为 null

4. 设置对象头

对象头存储了对象的元数据信息,包括:

  • Mark Word:存储对象的哈希值、GC 分代年龄、锁状态等信息。

  • 类指针:指向对象所属类的元数据。

  • 数组长度(仅数组对象)。

5. 执行构造方法

  • 调用类的构造方法,按照代码中的逻辑为字段赋值。

  • 包括显式初始化和静态代码块的执行。

6. 返回对象引用

  • 对象创建完成后,返回对象的引用,供程序使用。

知识扩展

1. 指针碰撞 vs 空闲列表

  • 指针碰撞

    • 高效,但需要垃圾收集器整理堆空间。

    • 适用于 复制算法标记整理算法

  • 空闲列表

    • 更灵活,适用于内存碎片较多的情况。

    • 常见于 标记清除算法

2. JVM 如何保证线程安全

  • TLAB:每个线程有独立的内存分配区域,减少竞争。

  • CAS:通过原子性操作分配内存,确保分配过程线程安全。

3. 大对象的分配

  • 大对象(如大数组、长字符串)通常直接分配到老年代,避免在新生代中频繁移动。

总结

JVM 创建对象的过程包括检查类加载状态、分配内存、初始化、设置对象头和调用构造方法等。

通过优化分配方式(指针碰撞、空闲列表)和线程安全机制(TLAB、CAS),JVM 能够高效且安全地完成对象创建过程。

公众号.png

1
JVM
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin
    1. 支付宝打赏

      qrcode alipay
    2. 微信打赏

      qrcode weixin
博主关闭了所有页面的评论