对象的创建
Object obj=new Object();
当碰到一个new指令时,jvm首先检查对应的类是否已经加载到jvm中,如果没有加载,需要先对类进行加载。
类加载分为5个步骤:
1.加载
通过类的全限定名获取对应的类定义数据的字节流加载到jvm的方法区中,并在内存生成对应的Class对象。
2.验证
验证Class定义的合法性,确定符合虚拟机的规范,保证虚拟机运行时的安全。
3.准备
为类变量分配内存并设置初始值,类的常量(被final修饰的类变量)直接初始化为常量值。
4.解析
将常量池中的符号引用替换为直接引用,得到类,字段或者方法在内存中的指针或者偏移量。
5.初始化
执行静态代码块和为静态变量赋值,如果存在父类,则先初始化父类。
类加载完成,方法区储存当前类的类信息。
类加载后,接着执行对象的创建
1.在堆中为对象分配内存
2.将内存空间初始化为零值
3.设置对象头信息
设置对象所属的类(类型指针),对象的哈希码,GC分代年龄等
4.执行对象的初始化方法
分配内存方式
1.指针碰撞
对于规整的堆内存,所有用过的内存都放在一边,空闲的放在另一边,中间放着一个指针作为分界指示器,分配内存就把指针向空闲的内存挪动一段与对象大小相等的距离。
2.空闲列表
堆的内存不规整的情况下(有内存碎片),虚拟机维护了一个列表,记录哪些内存时可用的,在分配的时候查找一块足够大的内存空间划分给对象实例。
出于并发申请分配的考虑,避免并发冲突,虚拟机采用了线程预分配的机制,即本地线程分配缓冲(TLAB)。
线程创建时都在队中预先分配一小块内存区域,只有在用完时并重写分配才需要进行通过锁定。(CAS+重置机制)