一 对象的内存布局:

  在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. 使用kafka-python客户端进行kafka kerberos认证

    之前说过python confluent kafka客户端做kerberos认证的过程,如果使用kafka python客户端的话同样也可以进行kerberos的认证,具体的认证机制这里不再描述,主要 ...

  2. JVM探究之 —— 类加载器-双亲委派模型

    虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这个动作的代码模块称为“类加载器 ...

  3. [清华集训2015]灯泡(浙江大学ZOJ 3203 Light Bulb)

    Time Limit: 1 Second      Memory Limit: 32768 KB Compared to wildleopard's wealthiness, his brother ...

  4. RequireJS - 快速指南

    原文: https://www.tutorialspoint.com/requirejs/requirejs_quick_guide.htm RequireJS - 概述 RequireJS是一个Ja ...

  5. openwrt如何打开linux内核的CONFIG_DEVMEM选项?

    答: 直接在openwrt的make menuconfig中打开CONFIG_KERNEL_DEVMEM选项即可

  6. Java基础 awt Button 鼠标放在按钮上背景颜色改变,鼠标离开背景颜色恢复

        JDK :OpenJDK-11      OS :CentOS 7.6.1810      IDE :Eclipse 2019‑03 typesetting :Markdown   code ...

  7. Nodejs 包与 npm第三方模块安装和 package.json 以及 cnpm

    包与 NPM 1. 包 Nodejs 中除了它自己提供的核心模块外,可以自定义模块,也可以使用第三方的模块.Nodejs 中第三方模块由包组成,可以通过包来对一组具有相互依 赖关系的模块进行统一管理. ...

  8. 接口项目servlet的一种处理方式,将异常返回给调用者【我】

    接口项目servlet的一种处理方式,其他层有异常全部网上抛,抛到servlet层,将异常返回给调用者: Servlet层: private void processRequest(HttpServl ...

  9. C++ Multimap运用实例—查找元素

    C++ Multimap运用实例—查找元素 #include <map> #include <iostream> #include <algorithm> #inc ...

  10. Tensorflow不能使用GPU的解决办法

    转载:https://blog.csdn.net/kudou1994/article/details/86735451 服务器在训练模型,另一边我在瞎胡乱搞不晓得咋个搞的,就不能使用GPU了.pyth ...