JVM——对象的创建过程

对象的创建过程:

我们在Java代码中new 一个对象时,我们很难看到对象创建的过程,尤其是在jvm内存中的过程,下面来介绍一下对象创建在jvm中的过程:

    对象实例在jvm中是存在于java堆中的,每一个对象实例都会占用一定的内存空间,

    当new执行时,首先会加载new的类

    当类加载完成之后,实例对象所占的大小就确定了。

    此时,jvm会在java堆中为实例对象开辟一块内存空间,用于存储对象实例。并且设置对象属于哪个类、如何找到对象(指针或地址)、对象的哈希码、对象的GC分代年龄等信息,这些信息存储在对象头中,还进行了对象属性的零值初始化。

    此时对于虚拟机来说已经完成了创建对象,但是对于java程序来说才好刚刚开始,对象初始化的init方法还没有执行。但是此时虚拟机已经进行了对象得零值设置,所以即使不执行init方法,程序中也是可以正常是用对象实例的。

实例化对象过程中的注意事项以及方法:

jvm为实例对象分配空间主要有两种方法

        一:指针碰撞:这种方法是在java堆中,将已用内存和未用的内存分开成两部分,两部分内存之间放这一个指针作为分界点,当有新的实例对象需要分配内存空间时,指针向未用内存一侧移动相应大小的距离,将新的实例对象存储在该内存空间上。这种方式需要内存是规整的。

        二:空闲列表:这种方法分配空间是随机,每次分配内存空间都是从空闲的内存中选取一块分配给实例对象。那么就需要一个列表来存放这些空闲的内存空间地址,每当有实例对象需要空间,就从这个列表中选取出一块内存分配给实例对象。这种情况下内存是不规则的。

        两种方法的选择取决于内存的结构是否规整,而内存结构是否规整则取决于采用的垃圾回收器是否带有压缩整理功能。

        例如:Serial、ParNew等带有compact过程的收集器,就是带有压缩整理功能的

                    CMS这种基于Mark—Sweep算法的收集器就是没有压缩整理功能的

    有些时候,创建对象操作很频繁,这样就有可能导致指针刚刚分配好,还没来得及创建对象,就被另一个线程抢先,先占用了指针,这时候就会产生问题,解决这种问题主要有两种办法:

        一:对创建对象动作行为进行同步处理,这种同步处理实质是CAS配上失败重试的方式实现保证更新操作的原子性的。

        二:把每一个创建对象的动作行为按照线程划分为不同的空间中进行,这种方式就是将创建对象行为放入到线程中,为每一个线程分配一小块内存空间(TLAB),每个线程要分配内存就在自己的TLAB上运行分配,只有当TLAB满了,需要重新分配TLAB时,才需要进行同步锁定。

        TLAB方式的开启需要通过-XX:+/-UseTLAB参数设定。

### JVM对象实例化的具体过程 #### 类加载阶段 在 Java 虚拟机 (JVM) 中,当程序首次使用某个类时,该类会被加载到 JVM 的方法区。这一过程中包含了三个主要子步骤:加载、连接和初始化[^1]。 - **加载**:查找并加载类的二进制数据至内存。 - **验证**:确保被加载类的数据格式正确无误。 - **准备**:为类中的静态变量分配内存空间,并将其初始化为默认值。 - **解析**:将常量池内的符号引用转换成直接引用。 - **初始化**:这是最后一个阶段,在此期间,JVM负责执行类构造器 `<clinit>` 方法来显式地给静态字段赋初值以及运行任何静态初始块。 #### 内存分配 一旦类已经成功加载并且通过了上述各个阶段,则可以开始实际的对象创建流程。对于每一个创建对象而言: - 需要在堆中为其分配足够的连续内存区域用于保存其状态信息; - 同时也需要在其头部记录一些必要的管理信息,如哈希码、GC分代年龄等属性,这些都依赖具体的 JVM 实现而有所不同[^2][^3]。 #### 构造函数调用 紧接着便是对新建对象进行进一步配置的工作——即所谓的“实例化”。此时会涉及到两个重要概念:<code><init></code> 和构造方法: - <code><init></code>: 它是一个特殊的实例构造器,由编译器自动生成并嵌入到 .class 文件当中;它主要用于处理成员变量的初始化工作,包括但不限于设置默认值或是执行特定逻辑(如果存在非私有的实例初始化代码)[^4]。 - **构造方法**: 用户定义的方法之一,用来完成更复杂的初始化操作,例如接收参数传递过来的信息以构建完整的业务实体。值得注意的是,尽管二者看起来相似但实际上它们属于不同层面的概念—前者偏向底层机制后者则更加贴近应用层面上的需求。 综上所述,整个对象实例化进程不仅涉及到了多个层次上的准备工作(从类级别直到单个个体),同时也体现了高度抽象的设计理念使得开发者能够专注于编写高效可靠的软件而不必过分关心底层细节。 ```java // 创建一个新的 Student 对象示例 Student student = new Student(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值