对象的创建

Step1 类加载检查

当发现一条new指令时,检查:

  1. 该指令的参数是否能在常量池中定位到一个类的符号引用;
  2. 并且检查这个符号引用代表的类是否已经被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。

Step2 为新生对象分配内存

对象所需的内存大小在类加载完成之后便可完全确定。分配方式有两种,选择哪种分配方式由java堆是否规整决定;而java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。

两种分配方式:

  1. 指针碰撞(Bump the Pointer): 内存规整
  2. 空闲列表 (Free List): 内存不规整

Step3 分配内存如何保证线程安全

两种方案:

  1. 所有分配内存动作进行同步处理。(不推荐)
  2. 每个线程在java堆预先分配一小块内存,称为本地线程分配缓存(Thread Local Allocation Buffer, TLAB)。各个线程会先在TLAB里面分配内存,该操作不用同步。只有当TLAB用完并分配新的TLAB时,才需要同步锁定。虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB参数来设定。

Step4 初始化为零值

虚拟机将分配到的内存都初始化为零值(不包括对象头)。如果使用TLAB,这一步可以提前到TLAB分配时进行。

保证了对象的实例字段可以不赋初始值就能直接使用。

Step5 对象头必要设置

例如,这个对象是哪个类的实例、如何找到类的元数据,对象的hash code, GC分代年龄,是否启用偏向锁...

Step6 执行init方法

<init>执行之前,所有值都是零值。执行完new指令后,会接着执行<init>,把对象按照程序员的意愿初始化。

对象的内存布局

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

Part1 对象头(Header)

细分为两部分:

  1. Mark Word, 存储对象自身的运行时数据 :哈希码hashcode, GC分代年龄, 锁状态标志,线程持有的锁。。。这部分数据很多, 虚拟机为其分配的32bit (32位虚拟机) / 64bit (64位虚拟机) 不够用,因为会根据对象的状态复用自己的存储空间。
  2. 类型指针:即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
  3. (仅针对java数组):有一块区域保存数组长度

Part2 实例数据(Instance Data)

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

  • 无论是父类的继承来的,还是在子类定义的,都要记录;
  • 记录顺序受到:1.虚拟机分配策略参数(FieldsAllocationStyle); 2.字段在java源码中定义的顺序
  • 默认的分配策略:long/double, int, short/char, byte/boolean, oops(Ordinary Object Pointers)...相同宽度的字段总是优先分配在一起。
  • 在默认的情况下,父类中定义的变量会出现在子类之前;当CompactFields值为true时(默认为true),那么子类中较窄的变量也可能插入到父类变量的空隙之中。
精度(低1-高5)    
1 byte(1字节) Byte
short(2字节) Short
char(2字节) Character
     
2 int(4字节) Integer
     
3 long(8字节) Long
     
4 float(4字节) Float
     
5 double(8字节) Double
     
NA boolean(未定) Boolean

Part3 对齐填充(Padding)

不是必须存在的,也没有特别的意义,就是占位符。HotSpot VM 的自动管理系统要求对象起始地址/对象的大小必须是8字节的整数倍。

  • 对象头部分正好是8字节的倍数(1倍或者2倍)
  • 当对象实例数据没有对齐时,就需要通过对齐填充来补全。

Java 虚拟机 - 2.3 HotSpot虚拟机对象的更多相关文章

  1. 深入理解Java虚拟机读书笔记1----Java内存区域与HotSpot虚拟机对象

    一 Java内存区域与HotSpot虚拟机对象 1 Java技术体系.JDK.JRE?     Java技术体系包括:         · Java程序设计语言:         · 各种硬件平台上的 ...

  2. JDK1.8-Java虚拟机运行时数据区域和HotSpot虚拟机的内存模型

    目录 介绍 官方文档规定的运行时数据区域 程序计数器 Java虚拟机栈 本地方法栈 虚拟机栈和本地方法栈溢出 Java堆 演示堆内存溢出 方法区 运行时常量池 演示方法区溢出 HotSpot虚拟机的内 ...

  3. Java内存区域与内存溢出异常--HotSpot虚拟机对象探秘

    以常用的HotSpot和常用的Java堆为例,深入探讨HotSpot虚拟机在Java堆中对象分配.布局和访问的全过程 1.对象的创建 ①虚拟机遇到一条new指令后,首先将去检查这个指令的参数是否能够在 ...

  4. 【深入理解JAVA虚拟机】第二部分.内存自动管理机制.2.HotSpot虚拟机对象探秘

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

  5. java对象在内存中的结构(HotSpot虚拟机)

    一.对象的内存布局 HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 从上面的这张图里面可以 ...

  6. 《深入理解java虚拟机》笔记(2)HotSpot虚拟机对象探秘

    一.对象的创建 1.类加载: 虚拟机在遇到一条new指令时候,检查类是否已被加载.解析.初始化过,如果没有,则执行类加载过程. 2.分配内存:类加载完成后,则为新对象从java堆上分配内存,分配内存有 ...

  7. Java虚拟机系列(二)---HotSpot虚拟机对象

    都知道Java是一门面向对象的编程语言,在Java程序运行过程中,无时无刻不在创建对象,所以这节来总结一下HotSpot虚拟机中的Java对象. 一.Java虚拟机对象的创建过程. 在语义层面创建一个 ...

  8. 深入理解Java虚拟机-HotSpot虚拟机对象探秘

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

  9. HotSpot虚拟机对象介绍

    1.对象的创建 Java是一门面向对象语言,在运行过程中无时不刻不在创建对象.从语言层面,创建对象仅仅是一个new关键字而已,而在虚拟机中,对象(文中讨论的对象仅限于普通java对象,不包含数组和Cl ...

随机推荐

  1. 集成 Swagger2 构建强大的 RESTful API 文档

    微信公众号:一个优秀的废人如有问题或建议,请后台留言,我会尽力解决你的问题. 前言 快过年了,不知道你们啥时候放年假,忙不忙.反正我是挺闲的,所以有时间写 blog.今天给你们带来 SpringBoo ...

  2. DO_DEVICE_INITIALIZING

    这个东西的位置在DEVICE_OBJECT的Flags字段中, 本来这个Flags大多的情况下都是在设置IO方式,如DO_BUFFERED_IO, 但特殊的位也可能需要在这里设置. 用处是防止当自己的 ...

  3. wordpress Warning: Parameter 2 to qtranxf_postsFilter() expected to be a reference

    wordpress qtranslate-x Warning: Parameter 2 to qtranxf_postsFilter() expected to be a reference Para ...

  4. DataTable转对象Model

    我们经常需要从数据库表中取数,取数是以取DataTable的方式,但是我么希望以对象为单位进行这种操作.即存在把取到的DataTable(数据表)转换为ModelList(对象集合)的需求. 原理稍微 ...

  5. 【命令】Maven命令

    当前项目的依赖树: mvn dependency:tree -U.-B.-e -U参数: 该参数能强制让Maven检查所有SNAPSHOT依赖更新,确保集成基于最新的状态,如果没有该参数,Maven默 ...

  6. 7.12模拟T2(套路容斥+多项式求逆)

    Description: \(n<=10,max(w)<=1e6\) 题解: 考虑暴力,相当于走多维格子图,不能走有些点. 套路就是设\(f[i]\)表示第一次走到i的方案数 \(f[i] ...

  7. 好用的日期控件jeDate

    最近做公司后台系统关于仓库的一些东西,需要根据时间范围来导出一些数据,我们使用的后台框架是基于bs的,bs也有时间控件:bootstrap-datepicker是只能选择日期的, daterangep ...

  8. GetWindowLong

    函数功能:该函数获得有关指定窗口的信息,函数也获得在额外窗口内存中指定偏移位地址的32位度整型值. 函数原型:LONG GetWindowLong(HWND hWnd,int nlndex): 参数: ...

  9. NOIp2018集训test-9-19(am&pm)

    AM 这是一套在长沙考过而且我能记得全部正解的题,然后期望得分300实际得分155. T1 很套路,随便搞(我当年是怎么花大半场时间写T1并且写出现在两倍长的代码的??) //Achen #inclu ...

  10. NX二次开发-UFUN编辑图层类别名字UF_LAYER_edit_category_name

    NX11+VS2013 #include <uf.h> #include <uf_layer.h> UF_initialize(); //创建图层类别 UF_LAYER_cat ...