深入理解JVM(二)–对象

楼市新闻行业动态 叭楼,新房带看,二手房代办过户望京二手房选房源,您置业的小管家。

1.对象的创建

(1)类加载过程

虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号代表的类是否已被加载、解析和初始化过,如果没有,先进行类加载过程。

(2)为新生对象分配内存

对象所需的内存大小在类加载完成后便可完全确定,为对象分配内存空间的任务相当于将一块确定大小的内存从java堆中划出来。分配内存有两种方法:指针碰撞和空闲列表。

指针碰撞:假设java堆中内存是绝对规整的,所有用过的内存都放到一边,空闲的内存放到另一边,中间放着一个指针作为分界点的指示器,分配内存时将指针向空闲空间挪一段与对象大小相等的距离。

空闲列表:如果java堆内存并不是规整的,已用的内存和空闲的内存交错。虚拟机维护一个列表,记录上哪些内存是可用的,在分配时从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录。

选择哪种分配方式由java堆是否规整决定,而java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。

多线程并发情况的解决方案:一种是虚拟机采用CAS配上失败重试的方式来保证更新操作的原子性,另一种方式是把不同线程内存分配的动作划分到不同的空间中处理,每个线程在Java堆上会事先分配一小块内存空间成为本地线程分配缓冲(TLAB),那个线程要分配内存就在那块TLAB上进行内存分配,只用当TLAB分配完成需要分配新的TLAB是才会进行同步锁定。

(3)内存空间初始化和对象设置

将分配到的内存空间都初始化为零值。如果使用TLAB,可提前至TLAB分配时进行。

接下来,虚拟机对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。

2.对象的内存布局

(1)对象头:一部分存储对象自身运行时的数据,另一部分时类型指针,即对象指向它的类元素数据指针,虚拟机通过这个指针来确定这个对象是那个类的实例。

(2)实例数据:对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。

(3)对齐填充:对象大小必须时8字节的整数倍,当对象实例数据部分没有对齐时,需要通过对齐填充来补全。

3.对象的访问定位

Java程序通过虚拟机栈中的reference数据来操作堆上的具体对象,这个引用去定位具体对象有两种方式: 句柄访问和直接指针访问。

句柄访问:Java堆中划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自的具体地址信息。

通过句柄访问对象

优点:reference中存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是很普遍的行为)时只会改变句柄中的实例数据指针,而reference本身不需要修改。

直接指针访问:Java堆对象中的布局必须考虑如何放置访问类型数据的相关信息,而reference中存储的直接是对象地址。

优点:访问速度快,节省了一次指针定位的时间开销。

通过直接指针访问对象
声明:本站内容来源于网络或叭楼会员发布,叭楼只作为信息发布平台,版权归原作者所有,本站不承担任何图片、内容、观点等内容版权问题,如对内容有歧义,可第一时间联系本站管理员发送邮件8309272@qq.com或者扫码微信沟通,经核实后我们会第一时间删除。 1.对象的创建(1)类加载过程虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号代表的类是否已被加载、解析和初始化过,如果没有,先进行类加载过程。(2)为新生对象分配内存对象所需的内存大小…
© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容