【JVM】Java对象创建的流程步骤

简介: 【JVM】Java对象创建的流程步骤

· 本文摘要

· 罗列Java创建对象的各种方式;

· 讲解Java对象创建的流程步骤;

一、Java创建对象的各种方式


   · 1. 用关键字new,老少皆知的方法:StringBuffer sb = new StringBuffer();

   · 2. 在单例模式(一种设计模式)中创建对象,本质上也是用关键字new,见下面的代码示例:

/**
 * 单例模式
 * 饿汉式(静态常量)
 */
public class BaseConfig {
    private final static BaseConfig INSTANCE = new BaseConfig();
    private BaseConfig () {}//私有构造子
    public static BaseConfig getInstance() {//在这里返回对象,其实也用了new
        return INSTANCE;
    }
}

   · 3. 在工厂模式Factory、建造者模式Builder(也是设计模式)中创建对象,本质上也是用关键字new

   · 4. 反射机制,利用Class.newInstance()。值得注意的是,Class.newInstance()创建对象时的特点有:弱类型,低效率,只能调用无参构造。这里还需要区别Class.forName()Class.forName()返回的是一个类,并不是对象。

 · 5. 利用Constructor.newInstance()Constructor.newInstance()可以调用任意构造函数。

   · 6. 使用克隆clone(),使用前保证对象实现了cloneable()

   · 7. 反序列化。开发中经常会对类实现序列化接口,反序列化支持我们把二进制数据、网络数据转化为Java对象保存在内存中。

   · 8. 使用第三方库Objenesis

二、Java创建对象的步骤


   · 第一步:检测类是否已经加载

  当JVM即将创建对象前,先去检查常量池中是否有此类的符号引用,并且检查此类是否已加载、链接、初始化。如果没有,需要类加载器来加载此类,参考:类加载器基础知识。

   · 第二步:为对象分配内存

类加载完成以后,虚拟机就开始为对象分配内存,此时所需内存的大小就已经确定了。只需要在堆上分配所需要的内存即可。


   具体的分配内存有两种情况:第一种情况是内存空间绝对规整,第二种情况是内存空间是不连续的。


       · 指针碰撞:假设Java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”(Bump the Pointer)。


       · 空闲列表:如果Java堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记 录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例, 并更新列表上的记录,这种分配方式称为“空闲列表”(Free List)。


 · 第三步:处理并发安全问题

由于对象分配的内存是放在堆中的,堆作为线程共享的数据区,当线程数大于1时,会涉及到线程安全问题。需要通过一定的方式来处理并发安全问题。

   第一种是采用同步的办法,为对象空间加锁,使用CAS来保证操作的原子性。

   另一种是每个线程分配内存都在自己的空间内进行,即是每个线程都在堆中预先分配一小块内存,称为本地线程分配缓冲(TLAB),分配内存的时候再TLAB上分配,互不干扰。


 · 第四步:初始化分配的空间

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头), 如果使用TLAB,这一工作过程也可以提前至TLAB分配时进行。这一步操作解释了对象的实例字段在Java代码中为什么可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。


 · 第五步:设置对象头

   分配完内存空间,初始化零值之后,虚拟机还需要对对象进行其他必要的设置,设置的地方都在对象头中,包括这个对象所属的类,类的元数据信息,对象的hashcode,GC分代年龄等信息。

在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了。但从Java程 序的视角来看,对象创建才刚刚开始<init>方法还没有执行,所有的字段都还为零。

  · 第六步:执行init方法(执行构造器)

相关文章
|
8月前
|
设计模式 网络协议 数据可视化
Java 设计模式之状态模式:让对象的行为随状态优雅变化
状态模式通过封装对象的状态,使行为随状态变化而改变。以订单为例,将待支付、已支付等状态独立成类,消除冗长条件判断,提升代码可维护性与扩展性,适用于状态多、转换复杂的场景。
1012 157
|
10月前
|
缓存 安全 Java
Java反射机制:动态操作类与对象
Java反射机制是运行时动态操作类与对象的强大工具,支持获取类信息、动态创建实例、调用方法、访问字段等。它在框架开发、依赖注入、动态代理等方面有广泛应用,但也存在性能开销和安全风险。本文详解反射核心API、实战案例及性能优化策略,助你掌握Java动态编程精髓。
|
10月前
|
安全 Oracle Java
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
684 0
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
|
10月前
|
存储 人工智能 JavaScript
Java从作用域到对象高级应用​
本内容详细讲解了JavaScript中的作用域类型(函数作用域、块作用域、全局作用域)、作用域链、垃圾回收机制、闭包、变量提升、函数参数、数组方法、内置构造函数、对象高级知识、原型链、对象赋值、深浅拷贝、递归、异常处理及this指向等内容,全面覆盖JS核心概念与编程技巧。
123 0
|
12月前
|
Java 数据库连接 API
Java 对象模型现代化实践 基于 Spring Boot 与 MyBatis Plus 的实现方案深度解析
本文介绍了基于Spring Boot与MyBatis-Plus的Java对象模型现代化实践方案。采用Spring Boot 3.1.2作为基础框架,结合MyBatis-Plus 3.5.3.1进行数据访问层实现,使用Lombok简化PO对象,MapStruct处理对象转换。文章详细讲解了数据库设计、PO对象实现、DAO层构建、业务逻辑封装以及DTO/VO转换等核心环节,提供了一个完整的现代化Java对象模型实现案例。通过分层设计和对象转换,实现了业务逻辑与数据访问的解耦,提高了代码的可维护性和扩展性。
465 1
|
12月前
|
前端开发 Java 数据库连接
java bo 对象详解_全面解析 java 中 PO,VO,DAO,BO,POJO 及 DTO 等几种对象类型
Java开发中常见的六大对象模型(PO、VO、DAO、BO、POJO、DTO)各有侧重,共同构建企业级应用架构。PO对应数据库表结构,VO专为前端展示设计,DAO封装数据访问逻辑,BO处理业务逻辑,POJO是简单的Java对象,DTO用于层间数据传输。它们在三层架构中协作:表现层使用VO,业务层通过BO调用DAO处理PO,DTO作为数据传输媒介。通过在线商城的用户管理模块示例,展示了各对象的具体应用。最佳实践包括保持分层清晰、使用工具类转换对象,并避免过度设计带来的类膨胀。理解这些对象模型的区别与联系。
941 1
|
11月前
|
存储 运维 Kubernetes
Java启动参数JVM_OPTS="-Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError"
本文介绍了Java虚拟机(JVM)常用启动参数配置,包括设置初始堆内存(-Xms512m)、最大堆内存(-Xmx1024m)及内存溢出时生成堆转储文件(-XX:+HeapDumpOnOutOfMemoryError),用于性能调优与故障排查。
1164 0
|
11月前
|
存储 Java
Java对象的内存布局
在HotSpot虚拟机中,Java对象的内存布局分为三部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。对象头包含Mark Word、Class对象指针及数组长度;实例数据存储对象的实际字段内容;对齐填充用于确保对象大小为8字节的整数倍。
217 0
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
1013 55
|
Arthas 监控 Java
Arthas memory(查看 JVM 内存信息)
Arthas memory(查看 JVM 内存信息)
1029 6