您的位置:首页 > 汽车 > 新车 > JVM—HotSpot虚拟机对象探秘

JVM—HotSpot虚拟机对象探秘

2024/11/16 20:43:34 来源:https://blog.csdn.net/m0_72983118/article/details/140776050  浏览:    关键词:JVM—HotSpot虚拟机对象探秘

1、对象的创建

对象只是普通对象,不包括数组和Class对象

  • 类加载检查:当虚拟机遇到字节码New指令时,先检查这个指令的参数是否可以在常量池定位到一个类的符号引用,并且加载这个符号引用代表的类是否被加载、解析、验证、初始化过。

  • 内存分配对象所需内存在类加载完成后就可以完全确定下来,实际上是在Java堆中划分一块定量大小的内存。

Java堆中内存分配有两种方式:

  1. 指针碰撞:假设Java堆中使用过的内存在一边,未使用过的内存在一边,中间有一个指针作为分界点指示器,分配内存就是将这个指针向空闲区移动一段与对象大小相等的距离。Serial、ParNew带压缩整理的的收集器就是采用这种算法。

  2. 空闲列表 :如果Java堆的内存并不是完整的,而是使用过的和未使用的相互交错,那么虚拟机就会维护一个列表,记录哪些内存块可用。分配的时候在列表中找到空间足够大的一块分给列表实例,并更新列表记录。

  • 内存空间初始化内存分配完成后,虚拟机需要将分配到的内存空间全都初始化零值。这步操作保证对象的实例字段在java代码中不赋值初始化也可以使用。

  • 设置对象头信息虚拟机还需要设置例如对象时哪个类的实例、如何找到对象元数据、对象哈希码,对象GC的年龄分代等信息。这些信息存放在对象头(Object Header)中。

  • init方法的执行从JVM角度来说对象已经创建完成,但是从Java程序的角度来说创建对象才刚开始。一般来说New指令执行完毕后会执行Class文件的<init>()方法。这样一个对象才完整的被创建。

2、对象的内存布局

在虚拟机里,对象的存储布局可以划分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

2.1 对象头

对象头通常包括两部分信息:

  • 1、存储对象自身运行时的数据—Mark Word

  • 2、类型指针,即对象指向它类型元数据的指针,JVM通过这个指针来确定对象属于哪个类的实例。并不是所有虚拟机都必须在对象数据上保留类型指针。

2.2 实例数据

实例数据是对象真正存储有效信息的的部分,即代码中定义的字段内容,不论是继承父类还是子类定义都需要记录。

这部分的存储会受到虚拟机分配策略参数和字段在Java源码中定义的顺序影响。

2.3 对齐填充

  • 这不是必然存在的,也没有特殊含义,仅仅起到占位符的作用。

由于HotSpot 虚拟机的自动内存管理系统要求对象起始必须是8字节的整数倍,因此对象实例数据部分没有对齐到8字节的整数倍,就需要对齐填充。

3、对象的访问定位

Java程序会通过上的reference数据来操作堆上的具体对象。

Java虚拟机并没有定义这个reference通过什么方式去访问,定位堆中对象的具体位置,主流有两种方式:

3.1 通过句柄访问对象

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

3.2 直接指针访问对象

Java堆中的对象的内存布局需要考虑如何放置类型数据的相关信息,reference中存储的是对象的直接地址,直接访问对象本身就不需要多一次间接开销。

使用直接指针的方式最大好处就是速度快,节省一次指针定位的开销。对于HotSpot就采用了第二种对象访问方式。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com