对象创建的5种方式
使用new关键字 | 调用了构造函数 |
---|---|
使用Class类的newInstance方法 | 调用了构造函数 |
使用Constructor类的newInstance方法 | 调用了构造函数 |
使用clone方法 | 没有调用构造函数 |
使用反序列化 | 没有调用构造函数 |
普通java对象创建过程步骤
- 碰到new指令创建对象时,检查这个new指定的参数在常量池中是否存在对应的符号引用,并查看这个类是否被加载过,没加载的话先进行类加载过程(第7章节)。
- 确定对象所需分配内存大小(类加载完成后对象大小便可以确定了)。
- 在java堆中进行内存分配
需要考虑的两大类问题
3.1. 怎么进行分配(内存分配算法)
- “指针碰撞” 分配方法
- “空闲列表”分配方法
3.2. 多线程并发分配问题怎么解决 - 方式一:并发内存分配操作进行去锁控制并发方式-虚拟机采用CAS+失败重试方式保证更新操作的原子性
- 方式二:内存分配操作每个线程在线程单独空间中分配,来避免并发问题。每个线程预先分配一块内存空间,叫本地线程分配缓存(Thread Local Allocate Buffer,TLAB)。只有TLAB内存分配完需要分配新的TLAB是,才需要同步锁,避免直接加锁操作。
(-XX:+/-UseTLAB参数:确定虚拟机是否使用TLAB) - 内存空间初始化零值。(保证了对象实例字段可以不初始化便能直接使用,真正的初始化赋值语句再后面执行)
- 对象头初始化(表示该对象是哪个类的实例,如何查找类的元数据信息,对象hash码,对象的gc分代年龄,是否启用偏向锁等信息)
- 对象执行字节码<init>方法(对象实例字段进行赋值语句和执行{}方法块)
数组对象创建
Class对象创建过程