JVM是如何创建对象的?

1 个回答

  • 叶家少主
    世界上没有快乐的地方,只有快乐的人。
    ### **JVM 创建对象的过程** JVM 在创建对象时主要经历以下步骤: ### **1. 检查类的加载状态** - JVM 会检查指令中引用的类是否已被加载、解析和初始化。 - 如果类未被加载,则触发类加载过程,完成加载、链接和初始化。 ### **2. 分配内存** JVM 会在堆中为对象分配内存空间。分配方式取决于堆的状态: 1. **指针碰撞**(Bump-the-pointer): - 适用于堆内存是规整的情况(所有已分配和未分配内存分布在两侧)。 - JVM 使用一个指针记录当前可用的内存地址,分配时将指针向前移动分配内存。 - 高效,但需要堆经过垃圾收集后保持规整。 2. **空闲列表**(Free-list): - 适用于堆内存存在碎片的情况(内存分布不连续)。 - JVM 维护一个空闲列表,记录所有未分配内存块。分配时遍历空闲列表,找到足够大的块。 **并发内存分配的安全性:** - **CAS + 失败重试**:利用原子操作确保多线程分配内存的安全性。 - **Thread Local Allocation Buffer (TLAB)**:为每个线程分配一个私有内存区域,用于分配小对象,减少锁竞争。 ### **3. 内存初始化** - JVM 将分配到的内存空间初始化为零值,确保对象字段具有默认值: - 基本类型:`int` 为 `0`,`boolean` 为 `false` 等。 - 引用类型:初始化为 `null`。 ### **4. 设置对象头** 对象头存储了对象的元数据信息,包括: - **Mark Word**:存储对象的哈希值、GC 分代年龄、锁状态等信息。 - **类指针**:指向对象所属类的元数据。 - **数组长度**(仅数组对象)。 ### **5. 执行构造方法** - 调用类的构造方法,按照代码中的逻辑为字段赋值。 - 包括显式初始化和静态代码块的执行。 ### **6. 返回对象引用** - 对象创建完成后,返回对象的引用,供程序使用。 ### **知识扩展** #### **1. 指针碰撞 vs 空闲列表** - **指针碰撞**: - 高效,但需要垃圾收集器整理堆空间。 - 适用于 **复制算法**、**标记整理算法**。 - **空闲列表**: - 更灵活,适用于内存碎片较多的情况。 - 常见于 **标记清除算法**。 #### **2. JVM 如何保证线程安全** - **TLAB**:每个线程有独立的内存分配区域,减少竞争。 - **CAS**:通过原子性操作分配内存,确保分配过程线程安全。 #### **3. 大对象的分配** - 大对象(如大数组、长字符串)通常直接分配到老年代,避免在新生代中频繁移动。 ### **总结** JVM 创建对象的过程包括检查类加载状态、分配内存、初始化、设置对象头和调用构造方法等。通过优化分配方式(指针碰撞、空闲列表)和线程安全机制(TLAB、CAS),JVM 能够高效且安全地完成对象创建过程。
    编辑于 2025-01-02 22:02 •IP属地 美国
    举报
    评论
    收藏