JVM对象创建过程


在java中,对象的创建仅仅只是new一下而已,但是其实远远没有这么简单.

一. 检查是否类是否加载

当java虚拟机遇到一条new指令对应的字节码时候,首先将会去检查这个指令的参数能否在常量池中,获取到一个类的符号引用.并且检查这个符号引用代表的类是否被加载,解析和初始化过.如果没有,那么就先执行类的加载过程.

二. 分配内存

对象所需要的内存大小,在类加载之后就可以确定.所以就是从java堆内存中划分一块确定的内存出来.

如何分出来有两种方法.

1. 指针碰撞

假设堆内存中是规整连续的,使用过和没使用过的严格分开,这样只需要维护一个指针,分配内存之后,移动一下指针就可以了

在这里插入图片描述

2. 空闲列表

如果java堆内存并不规整,已使用和未占用杂乱放置,就无法使用简单碰撞

如下图所示,实际要复杂的多,不同区块的大小也不一样,当有新的对象需要分配内存时候,就从空闲列表中取出一块足够大的内存分配给它(能力有限,怎么简单怎么画了)

在这里插入图片描述

内存分配总结

一般带有压缩整理功能的(ParNew),可以使用指针碰撞方法分配内存,基于标记-清除算法的(CMS),一般使用空闲列表

HotSpot虚拟机有一些改进,在cms回收器的实现下,会先使用空闲列表,先拿到一些大块的内存,在这些大块的内存里面,又可以使用指针碰撞方法

如果只按照上面的分配内存的办法,是会产生线程安全问题,所以实际上,在分配内存的时候,还会加入cas失败重试的机制

三. 将对象的属性初始化为零值

四. 设置对象头信息

对象头包括两类信息

  1. 存储对象自身的运行时数据

    如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等

  2. 类型指针

    即对象指向它的类型元数据的指针,Java虚拟机通过这个指针来确定该对象是哪个类的实例

  3. 如果是数组,还要包括数组的长度信息

五. 执行init方法,也就是java的构造函数

其实上面四步执行完,虚拟机的对象创建已经完成,后面的init方法即java中的构造函数,就是程序员按照自己意愿对此对象进行的初始化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值