虚拟机中对象的创建

一、对象的创建
1. Java创建对象的四种方式

(1)通过 new 语句来实例化一个对象;

(2)通过反射机制创建对象;

(3)通过 clone()方法(复制)创建对象;

(4)通过反序列化的方式创建;

2.虚拟机创建对象的过程

(1)当虚拟机遇到一条字节码 new 指令时,首先检查这个指令的参数是否能在常量池中找到一个类的符号引用,并且检查这个符号引用代表的类是否被加载,解析,初始化过,如果没有,就必须先执行类加载过程;

(2)虚拟机为新生对象分配内存空间 :有如下两种分配方式:

  • 指针碰撞 :假设Java堆中的内存时绝对规整的,把所有使用过的内存放到一边,所有空闲的内存放到另一边,中间放着一个指针作为指示器,所分配的内存就是把指针向空闲的方向移动对象大小的距离;
  • 空闲列表 :Java堆的内存并不规整,虚拟机需要维护一个列表,记录哪些内存块是可用的,分配时找到一块足够大的内存分配给对象实例,并更新列表上的记录;

分配方式的选择:选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整由所在采用的垃圾收集器是否带有空间压缩整理的能力决定。当采用Serial,ParNew 等带有压缩整理过程的收集器时,系统采用的分配算法是指针碰撞,既简单由高效。当采用的是使用CMS这种基于标记清除算法的收集器时,理论上只能采用较为复杂的空间列表来分配;

(3)内存分配完成之后,虚拟机必须将分配到的内存空间都初始化为零值,如果使用了 TLAB (本地线程分配缓冲)的话,这项工作也可以提前至 TLAB 分配时顺便进行。这步操作保证了对象实例字段再Java代码中可以不赋值就直接使用,使程序能访问到这些字段的数据类型所对应的零值;

(4)Java 虚拟机还要对对象进行必要的设置,例如:这个对象是哪个类的实例,如何才能找到类的元数据信息,对象的哈希码,对象的 GC 分代年龄等信息,这些信息存放在对象头中。

二、对象的内存布局

虚拟机中对象在堆中的存储布局可划分为三个部分:对象头,实例数据,对齐填充。

1.对象头

虚拟机对象的对象头部分包括两个部分的信息:

(1)储存对象自身的运行时数据: 如哈希码,GC年龄分代,锁状态标志,线程持有的锁,偏向线程ID,偏向时间戳等,官方称其为 “ Mark Word ” ;

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

(3)如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据;

2.实例数据

示例数据部分是对象真正存储的有效信息,即我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承过来的,还是在子类中定义的字段都必须记录起来,存储顺序会受到虚拟机分配策略参数和字段在Java源码中定义的顺序的影响;

3.对齐填充

这部分并不是必然存在的,也没有特别的含义,仅仅起到一个占位符的作用。这是由于Java 虚拟机的自动内存股那里喜用要求对象的起始地址必须是 8 字节的倍数,换句话说就是对象的大小必须是都是 8 字节的整数倍。对象头已经被精心设计成正好是 8 字节的倍数,如果示例数据部分不是 8 的倍数的话,就可以用对齐填充来补全对齐;

三、对象的访问定位

我们通过栈上的reference数据来操作堆上具体的对象,现在主流的方式有两种:

(1)使用句柄 :Java 堆中将可能会划分出一块内存来做句柄池,reference 中存储的就是对象的句柄地址,而句柄中包含了对象示例数据与类型数据各自具体的地址信息;

优点:reference 中储存的是稳定的句柄地址,在对象移动时只会改变句柄中的实例指针,而 reference 本身不需要被修改;

(2)直接访问 :Java堆中对象的内存布局就必须要考虑如何放置类型数据相关信息,reference 中存储的直接就是对象地址,如果只是访问对象本生的话,就不需要多一次间接访问的开销;

优点:速度快,对象访问在Java中非常的频繁,由于它节省了一次指针定位的时间开销,积少成多也是很可观的执行成本;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值