JVM系列之HotSpot虚拟机对象详解
Posted 若泽大数据
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM系列之HotSpot虚拟机对象详解相关的知识,希望对你有一定的参考价值。
对象的创建
当虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用是否已被加载、解析和初始化过,如果没有则会进行类加载过程。在类加载检查通过后,虚拟机给对象分配内存,对象所需的内存大小在类加载完成后便可确定。内存分配方式分为两种:一是“指针碰撞”,在Java堆中内存是绝对规整时(已用内存和空闲内存各占一边),通过改变分界点的指针为对象分配内存。二是“空闲列表”,如果堆中内存不是规整的,虚拟机就必须维护一个列表,记录哪些内存块是可用的,为对象分配足够内存后,更新列表上的记录。
PS:内存规整:Java堆内存是否规整取决定于垃圾收集器是否带有压缩整理功能决定,因此在使用Serial、ParNew等带有Compact过程的收集器时,采用的分配算法是指针碰撞,而使用CMS这种基于Mark-Sweep算法的收集器时,采用空闲列表。
对象的内存分部
在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。HotSpot虚拟机的对象的对象头包括两个部分信息,第一部分用于存储对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。这部分数据的长度在32位和64位的虚拟机中分别为32bit和64bit,官方称它为“Mark Word”。对象需要存储的运行时数据很多,往往会超过32位64位的Bitmap结构的限度,但是对象头信息是与对象自身定义数据无关的额外存储成本,考虑到虚拟机的控件效率,Mark Word 被设计成一个非固定的数据结构以便存储尽量多的信息,换句话说对象头是一个大于32位的不固定的数据结构。在32位HotSpot虚拟机中,如果对象处于未被锁定状态下,25bit用于存储对象哈希码,4bit用于存储对象分代年龄,2bit用于存储锁标志位,1bit固定为0。其他状态时对象存储内容如图:
对象的访问定位
Java程序需要通过栈上的reference数据来操作堆上的具体对象。由于reference类型在Java虚拟机规范中只规定了一个指向对象的引用,并没有定义这个引用应该通过何种方式去定位、访问堆中的位置,所以对象访问方式也是取决于虚拟机实现的。目前何种方式去定位、访问堆中的位置有使用句柄和直接指针两种。
使用句柄的好处:在对象被移动时(垃圾收集移动对象)时只会改变句柄中的实例数据指针,而reference不需要修改。有人比作它为二级指针。
使用直接指针的好处:好处就是快,节省了一次指针定位的时间开销。就HotSpot而言,它使用该方式进行对象访问。有人比作它为一级指针。
回归原创文章:
加我,进大数据V群
以上是关于JVM系列之HotSpot虚拟机对象详解的主要内容,如果未能解决你的问题,请参考以下文章