对象创建的过程
2020-04-05 12:44
204 查看
参考:https://www.cnblogs.com/chanshuyi/p/the_java_class_load_mechamism.html 必读
对上面文章进行总结:
-
-
准备阶段: 两个步骤
-
1.1 对类属性分配内存。
-
1.2 初始化内存为零。如果是
static final
并且赋值是字面量常量,就会直接赋值为给定值(在准备阶段也是会初始化的)
static final String s1 = new String("dddd"); // 类构造器中初始化 static final String s2 = "dddd"; // 准备阶段初始化
-
初始化阶段(重点)
- 2.1 初始化入口方法: main。执行main方法的类也会执行下面两个构造器(即便main是静态方法)
- 2.2 首先是执行类构造器(按顺序收集类中所有静态代码块和类变量赋值语句就组成了类构造器 )
- 2.3 后执行对象的构造器(按顺序收集成员变量赋值和普通代码块,最后收集对象构造器,最终组成对象构造器 )
- 注意:
如果
类构造器
中有对象实例化,就会执行该对象构造器 - 代码块只能访问之前定义的变量,但是可以赋值
- 对于静态字段,只有直接定义这个字段的类才会被初始化(执行静态代码块)。比如上面文章的
Son.factor
- 初始化入口方法。当进入类加载的初始化阶段后,JVM 会寻找整个 main 方法入口,从而初始化 main 方法所在的整个类。当需要对一个类进行初始化时,会首先初始化类构造器(),之后初始化对象构造器()。
在线代码练习:https://tool.lu/coderunner/?id=8w
-
加载类: 通过符号引用定位到类是否被加载。没有就加载类。执行类加载与验证的过程
-
验证:验证字节码,验证代码
-
准备阶段:重要 分配内存(针对类变量,对象属性在实例化的时候),初始化内存为0,对象为null。如果是
static final
的可以直接赋值为给定的值。
类加载完成后就能确定对象分配多少内存。如果虚拟机具有Compact
压缩功能(标记整理),就是用指针碰撞
(记录头尾位置);如果只有标记清理
的虚拟机,就是用空闲列表
。
分配内存的方式:CAS
与TLAB
两种。如果多线程并发创建,需要考虑同步问题(多个对象指向一个地方)。
-
CAS:一般使用
CAS
和失败重试保证原子性。 -
TLAB
:按照线程分配不同空间(本地线程分配缓冲),只有TLAB
用完,需要分配新的才需要同步。是否使用该方式通过参数指定
-
解析,符号引用替代成直接引用
-
初始化: 重要
-
分配到的内存初始化为零(除了对象头)。这就是对象属性不需要初始化可以直接使用
-
设置对象头:什么类的对象,元数据,哈希码,对象GC分代年龄等信息。根据虚拟机运行状态,判断是否启用偏向锁
-
执行类构造器,再执行对象的构造器
相关文章推荐
- Java对象在虚拟机中的创建过程
- Java创建对象过程中,内存的分配
- new关键字创建对象的过程
- HotSpot虚拟机对象揭秘之对象的创建过程探究
- 静态、三大代码块以及对象的创建过程
- Automation服务器不能创建对象的处理过程
- JVM - 对象的创建过程
- java引用对象和创建对象过程分析
- C++类对象创建过程揭密
- 对象创建过程/初始化顺序
- java 程序加载过程---3--类中申明同时申明类的静态对象 创建类的实例 访问类的静态变量 调用类的静态方法 使用反射方法 初始化类的子类对象 直接使用java.exe 调用某个类
- j2se之对象的创建过程
- Android应用程序窗口(Activity)的视图对象(View)的创建过程分析
- C++类对象创建过程揭密
- javascript对象创建过程
- java加载类创建对象的过程以及静态代码段的执行时机
- JavaScript 用new创建对象的过程
- Day10—继承、访问控制符、final关键字、对象创建过程、多态、抽象类
- 查询存储过程,数据库对象的创建历史