一 对象的内存布局:

  在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header),实例数据(Instance Data)和对齐填充(Padding)。

  HotSpot的对象头包括两部分信息,一部分存储对象运转时自身信息,例如hashCode,GC分代年龄,锁状态标志,线程持有的锁,偏向线程id,偏向时间戳等,这部分数据的长度在32和64位虚拟机中分别为32和64位,官方称之为“Mark World”。对象在运行时产生的数据很多,其实早已经超出了32或64位BitMap结构能承载的限度,考虑到虚拟机的空间效率,MarkWord被设计为一个非固定的数据结构以便在极小的内存空间中尽可能多的存储信息,他会根据对象的状态复用自己的内存,例如:在32位虚拟机中,如果对象处于未被锁定的状态下时,那32bit中25bit用于存储对象的哈希码,4bit存储对象分代年龄,2bit存储锁标志位,1bit固定为0,而在其他状态(轻量级锁定,重量级锁定,GC标记,可偏向)下存储结构如下:

  

  对象头的另一部分是类型指针,即对象指向它类元数据的指针,虚拟机通过该指针来确定这个对象是哪个类的实例,但并不是所有的虚拟机都是这样实现判断类型的。另外,如果对象是一个数组,那头对象中还需要有一块记录数组长度的数据,因为虚拟机可以通过普通对象的元数据确定对象的大小,但是从数组的元数据却无法确定数组的大小。

  接下来的实例数据部分存储的是对象的有效信息,也就是在程序代码中定义的各种类型的字段内容,无论是在父类中继承下来的还是在子类中定义的,都需要记录起来,这部分的存储顺序会受到虚拟机分配策略参数和字段在代码中定义顺序的影响。HotSpot定义的策略为long/doubles,ints,shorts/chars,bytes/booleans,oops,从分配策略看出,相同宽度的字段总是被分配到一起,在满足这个前提下,父类中定义的变量会出现在子类之前。

  第三部分对齐填充并不是必须存在的,也没有特殊的意义,但是由于HotSpot VM的自动内存管理系统要求对象的起始地址必须是8的整数倍,换句话说,每一个对象的大小都必须是8的整数倍,当对象所需要的内存不是8的整数倍时,才会使用对齐填充对齐来满足这一要求。

  二 对象的访问定位

  通过以上的步骤,一个对象就完成了内存分配和必要的初始化,那么我们如何才能定位到我们需要使用的对象呢?

  Java需要通过栈上的reference数据来操作堆上的具体对象,reference类型在Java虚拟机规范中只定义了一个指向对象的引用,但并没有规定以那种方式去定位和访问堆中对象的具体位置,所以对象的访问方式也是取决于虚拟机的实现方式,目前主流的实现方式有使用句柄和直接指针两种。

  句柄:

  如果使用这种实现方式,那么堆中就需要划分出一片内存来作为句柄池,reference中存储的就是对象的句柄地址,而在句柄中包含了对象的实例数据与类型数据各自的地址信息,如下图:

  使用直接指针进行访问,则reference中直接存储的就是对象地址,但是Java堆对象的布局中就必须考虑如何放置访问类型数据的相关信息,如下图所示:

  

  这两种方式各有好处,使用直接指针的好处就是更快,节省了一次指针定位的时间开销,而使用句柄的方式,在对象被移动(垃圾回收)时,不需要修改reference中的地址数据,只需修改句柄池中的数据。

  HotSpot当前采用的是直接指针的方式来访问对象。

  

深入理解JVM(三) -- 对象的内存布局和访问定位的更多相关文章

  1. JVM中对象的内存布局与访问定位

      一.对象的内存布局 已主流的HotSpot虚拟机来说,   在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header).实例数据(Instance Data)和对齐填 ...

  2. 【JVM之内存与垃圾回收篇】对象实例化内存布局与访问定位

    对象实例化内存布局与访问定位 从各自具体的内存分配上来讲 new 的对象放在堆中 对象所属的类型信息是放在方法区的 方法当中的局部变量放在栈空间 这 new 的对象怎么把三块粘合到一起 就是这章的内容 ...

  3. 关于Java的对象,锁和对象的内存布局、访问定位

    1. 对象的创建和分配 创建对象(如克隆.反序列化)通常仅仅一个new关键字,但在虚拟机中,对象的创建的过程需要如下步骤: 类加载检查 先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并 ...

  4. Java对象创建的过程及对象的内存布局与访问定位

    这里以HotSpot为例,且所说的对象指普通的Java对象,不包括数组和Class对象等. 1.对象创建的过程 1.类加载.解析.初始化:虚拟机遇到new时先检查此指令的参数是否能在常量池中找到类的符 ...

  5. JVM——深入分析对象的内存布局

    概述 一个对象本身的内在结构需要一种描述方式,这个描述信息是以字节码的方法存储在方法区中的.Class本身就是一个对象,都以KB为单位,如果new Integer()为了表示一个数据就占用KB级别的内 ...

  6. 【JVM第六篇--对象】对象的实例化、内存布局和访问定位

    写在前面的话:本文是在观看尚硅谷JVM教程后,整理的学习笔记.其观看地址如下:尚硅谷2020最新版宋红康JVM教程 一.对象的实例化 在平常写代码的过程中,我们用class关键字定义的类只是一个类的模 ...

  7. JVM 专题十二:运行时数据区(七)对象的实例化内存布局与访问定位

    1. 对象的实例化 1.1 创建对象的方式 new 最常见的方式 变形1 : Xxx的静态方法 变形2 : XxBuilder/XxoxFactory的静态方法 Class的newInstance() ...

  8. JVM运行时数据区--纵向补充--对象的实例化内存布局与访问定位

    对象的实例化 创建对象的方式 1.new:最常见的方式(本质是构造器) 变形1 : Xxx的静态方法 变形2 : XxBuilder/XxoxFactory的静态方法 2.Class的newInsta ...

  9. JVM详解(六)——对象的实例化、内存布局与访问定位

    一.对象的实例化 1.创建对象的方式 2.创建对象的步骤 脑图:https://www.processon.com/view/link/61701a927d9c087040525226 3.对象属性赋 ...

随机推荐

  1. uniapp - emmet

    话说,emment是官方uniapp直接引入的.基本上没做啥修改:可以点这里查看所有用法 - http://emmet.evget.com/ 1.类似css层级写法 1.1 view.ok>vi ...

  2. C# 序列化与反序列化之xml通过实现IXmlSerializable进行序列化的解决方案

    新建控制台console项目,添加XmlPersonIXmlSerializable类,和AddressIXmlSerializable类(实现IXmlSerializable)以及AddressIX ...

  3. xml报文标签替换正则表达式

    写在前面 需求是把所有标签中的信息替换成指定内容 例如: <transName>交易名称</transName><aaa></aaaa><tran ...

  4. android --------System.err: java.net.UnknownServiceException: CLEARTEXT .....

    1,当调用远程接口进行网络通信时,报如下错误: W/System.err: java.net.UnknownServiceException: CLEARTEXT communication to 1 ...

  5. sklearn的基本使用

    https://cloud.tencent.com/developer/news/58202 简介 今天为大家介绍的是scikit-learn.sklearn是一个Python第三方提供的非常强力的机 ...

  6. CentOS7下安装Mariadb 10.3.17

    1. install lsb packagesudo yum install -y redhat-lsb 2.install net-tools packagesudo yum install -y ...

  7. GIT删除本地tag和远程tag

    以tag test为例,这个tag已经同步到远程,但是现在发现了一个问题,需要撤回该tag,git命令如下: 删除本地tag: git tag -d test 删除远程tag: git push or ...

  8. Kubernetes 清除持续 Terminating 状态的Pods

    强制删除所有Pods -- 谨慎使用 kubectl delete pods --all --grace-period=0 --force

  9. 模态窗口showModalDialog的浏览器兼容解决方案【改】

    将代码中原来的 window.showModalDialog 全部替换成: showModalDialogN 然后增加方法: function showModalDialogN(uri, args, ...

  10. Hive学习笔记——metadata

    Hive结构体系 https://blog.csdn.net/zhoudaxia/article/details/8855937 可以在hive的jdbc接口中使用getMetaData方法来获取hi ...