java有两种对象:实例对象和Class对象,实例对象就通过Class对象来创建的,类是对象抽象和集合的话,Class类就是对类的抽象和集合,第一次创建对象时,Class动态加载到JVM中的(懒加载)
对象的创建
当虚拟机遇到字节码new指令时,检查指令的参数能否在常量池定位到符号引用,并检查这个引用代表的类是否加载,有或者加载完后,虚拟机为新生对象从堆中分固定大小的内存,这个大小在类加载完后是确定的。
分配内存有两种方式,取决于采用的垃圾收集器是否有空间压缩整理能力
1.对于规整的内存——指针碰撞
2.虚拟机维护一个可用内存列表——空闲列表
并发分配处理:
每个线程预分配一小块内存,即本地线程分配缓冲,缓冲分配完再采用CAS保证原子性
内存分配完成后,虚拟机将分配到的空间初始化为默认值(字段默认值),并且设置对象头
再执行init方法,相当于构造函数,对这个对象初始化(超类到子类static成员初始化,超类成员变量顺序初始化,超类构造方法。子类成员变量顺序初始化,构造方法调用)
对象在堆内存存储布局
1.对象头
包括两类信息
一.hashcode,GC分代年龄,锁状态标识,线程持有的锁,偏向线程ID,偏向时间戳等对象自身的运行时数据,即Mark Word。根据对象状态动态定义数据结构,复用存储空间
二.类型指针,指向它的类型元数据,虚拟机通过这个针确定对象属于哪个类的实例,如果对象是数组的话,还有一块记录其长度的数据
2.实例数据
记录所定义的各种类型的字段内容,包括从父类继承过来的,在其子类定义的字段
3.对齐填充
起占位符作用,对象的大小必须满足8字节的整数倍,对象头已设计为8字节的1或2倍,补实例数据的空缺
对象的访问定位
有虚拟机决定
1.句柄 2.直接指针