前言
在开发过程中如果要创建一个对象可以通过以下几种方式:
new、克隆(Clone)、反射(Class.forName(“类全限定名”).newInstance(),Constructor类的newInstance)。
今天只针对通过关键字new来创建对象作分析,通过new创建一个对象的方式如下:1
Object o = new Object();
但在new之后J虚拟机还会经过一系列的操作才能创建,今天来记录一下new之后的事情,以及对象的组成结构。
对象的创建
示意图
创建步骤
- 类的检查
在new指令之后首先在常量池中检查是否能定位到该类符号的引用。
如果没有定位到,则进行类的加载、解析和初始化 - 为对象分配内存
虚拟机将为对象分配内存,即把一块确定大小的内存从 Java 堆中划分出来
这种分配方式会根据堆内存是否整齐分成两种形式。
1.堆内存整齐:指针碰撞
2.堆内存零散:闲散列表
另外,为对象分配内存会引发线程不安全问题,解决方式是:
把内存分配行为 按照线程 划分在不同的内存空间进行 - 内存空间初始化为零值
内存分配完成后,虚拟机需要将分配到的内存空间初始化为零(不包括对象头) - 设置对象
主要是设置对象头,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息
对象内存布局
对象头
如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等
实例数据
对象真正有效的信息,即:代码中定义的字段内容
对齐填充
存储的信息:占位符,占位作用,因为对象的大小必须是8字节的整数倍。对象头的大小也是8字节的整数倍,如果实例数据不是8的整数倍的话(没对齐),则需要存储占位符,对齐填充。