今天小结下Java虚拟机创建普通Java对象的一般步骤,不包括class对象和数组。
S1. 检查new指令参数能否在常量池中定位到一个类的符号引用。
S2. 检查这个符号引用代表的类是否已经被加载、解析和初始化过。
如果该类没有被加载和初始化过,则必须先执行类的加载过程。
S3. 为新生对象分配内存
方法: if (java堆是规整的) then “指针碰撞”
if (java堆不规整) then “空闲列表”
附: 解决在并发情况下,对象创建修改不是线程安全的2种方案
方案一 对分配内存空间的动作进行同步处理。
其实Java虚拟机是采用CAS与失败重试相结合的方式保证更新操作的原子性的。
方案二 为每个线程预先分配一小块内存,称之为本地线程分配缓冲TLAB。
这种情况下,哪个线程要分配内存,就在哪个线程的TLAB上分配;当且仅当TLAB用完并分配新的TLAB时才需要同步锁定。
S4. 将分配到的内存空间都初始化为零值(不包括对象头)。
S5. 对对象进行必要设置。
根据虚拟机当前运行状态的不同,是否启用偏向锁等。
附:对象头中包含如下信息:对象是哪个类的实例;如何找到类的元数据信息;对象的哈希码;对象的GC分代年龄等。