HotSpot创建对象探秘

3 篇文章 0 订阅
虚拟机中执行new执行的过程
1、在常量池中检查存在这个类的符号引用。(找不到就抛出ClassNotFoundException)
2、检查这个符号引用对应的Class是否被加载、解析、初始化过等。如果没有就进行初始化 (注1)
3、为对象在堆中进行内存分配,(所需要的内存大小已经在类加载过程中确定,都是固定大小)(注2)
4、虚拟机要对对象进行必要的设置;如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。
5、初始化对象的构造函数。

对象的内存布局
对象在内存存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。
1、对象头包括两部分数据:第一部分用户存储对象自身的运行时数据,(如 哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等)。第二部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
2、实例数据存储对象真正有效的数据。
3、对齐填充,并不是必然存在的。比如HotSpot VM 要求对象的其实位置为8的倍数,所以将不足8位的地方进行补齐。

对象定位访问
主流的访问方式有使用句柄和直接指针两种
1、使用句柄访问,那么在Java堆中划分出一部分内存作为句柄池,reference中存储的就是对象的句柄地址,句柄地址中包含对象的实例数据与类型数据各自具体的地址信息。
优势:使用句柄来访问的最大好处就是reference中存储的是文档的句柄地址,在对象被移动时只会改变句柄的实例数据指针,而reference本身不需修改啊
2、如果使用直接指针访问,那么Java堆对象的布局中必须考虑如何存放对象类型数据的相关信息。
优势:使用指针访问访问方式最大的好处是速度更快,它节省了一次指针定位的时间开销,由于对象的访问在Java中非常频繁,因此这类开销积少成多后也是一项非常可观的执行成本。






注1:java中类的加载顺序介绍(http://blog.csdn.net/eff666/article/details/52203406)
注2:这里指的对象是普通Java对象不包括数组对象和Class对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值