您的位置:首页 > 编程语言 > Java开发

对象创建的过程

2020-04-05 12:44 204 查看

参考:https://www.cnblogs.com/chanshuyi/p/the_java_class_load_mechamism.html 必读

对上面文章进行总结:

    1. 准备阶段: 两个步骤
  • 1.1 对类属性分配内存。

  • 1.2 初始化内存为零。如果是static final并且赋值是字面量常量,就会直接赋值为给定值(在准备阶段也是会初始化的)

static final String s1 = new String("dddd"); // 类构造器中初始化
static final String s2 = "dddd"; // 准备阶段初始化
    1. 初始化阶段(重点)
    • 2.1 初始化入口方法: main。执行main方法的类也会执行下面两个构造器(即便main是静态方法)
    • 2.2 首先是执行类构造器(按顺序收集类中所有静态代码块和类变量赋值语句就组成了类构造器 )
    • 2.3 后执行对象的构造器(按顺序收集成员变量赋值和普通代码块,最后收集对象构造器,最终组成对象构造器 )
    • 注意: 如果类构造器中有对象实例化,就会执行该对象构造器
    • 代码块只能访问之前定义的变量,但是可以赋值
    • 对于静态字段,只有直接定义这个字段的类才会被初始化(执行静态代码块)。比如上面文章的Son.factor
    • 初始化入口方法。当进入类加载的初始化阶段后,JVM 会寻找整个 main 方法入口,从而初始化 main 方法所在的整个类。当需要对一个类进行初始化时,会首先初始化类构造器(),之后初始化对象构造器()。

    在线代码练习:https://tool.lu/coderunner/?id=8w

    1. 加载类: 通过符号引用定位到类是否被加载。没有就加载类。执行类加载与验证的过程

    2. 验证:验证字节码,验证代码

    3. 准备阶段:重要 分配内存(针对类变量,对象属性在实例化的时候),初始化内存为0,对象为null。如果是static final 的可以直接赋值为给定的值。

    类加载完成后就能确定对象分配多少内存。如果虚拟机具有Compact压缩功能(标记整理),就是用指针碰撞(记录头尾位置);如果只有标记清理的虚拟机,就是用空闲列表。 分配内存的方式:CASTLAB两种。如果多线程并发创建,需要考虑同步问题(多个对象指向一个地方)。

    • CAS:一般使用CAS和失败重试保证原子性。

    • TLAB:按照线程分配不同空间(本地线程分配缓冲),只有TLAB用完,需要分配新的才需要同步。是否使用该方式通过参数指定

    1. 解析,符号引用替代成直接引用

    2. 初始化: 重要

    • 分配到的内存初始化为零(除了对象头)。这就是对象属性不需要初始化可以直接使用

    • 设置对象头:什么类的对象,元数据,哈希码,对象GC分代年龄等信息。根据虚拟机运行状态,判断是否启用偏向锁

    • 执行类构造器,再执行对象的构造器

  • 内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签:  java cas