2.3.1对象创建

Java是一门面向对象的语言,在Java程序的运行过程中无时无刻都有新的对象被创建出来。从语言的层面看,创建对象通常仅仅是一个new关键字而已,从虚拟机的角度看,创建对象又是怎样的一个过程呢?

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

在类加载检查通过后,接下来虚拟机将为新生对象分配内存。对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间其实就是把一块大小确定的内存从java堆中划分出来。

假设Java堆中内存是绝对规整的,所有用过的内存放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那分配内存的工作其实就是将这个指针向空闲空间挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”。

如果Java堆中的内存并不是规整的,已使用的内存和未使用的内存交错存在,那就没有办法进行简单的指针碰撞了,虚拟机必须维护一个列表,记录哪些内存是尚未使用的、可分配的,在分配内存的时候从列表中找到一块足够大的空闲空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”

具体使用哪种方式分配内存由Java堆是否规整决定,而Java堆是否规整又由采用的垃圾收集器是否带有压缩整理功能决定。

​​

除了如何划分可用空间,另外还需要注意空间划分时的线程安全问题。对象的创建在虚拟机中是非常频繁的,以较为简单的“指针碰撞”为例,即使只是简单的修改指针指向的位置,在在并发情况下一样存在线程安全问题,比如说正在给A分配内存,指针还没来得及修改,对象B也请求分配内存,也需要修改指针。

上述问题有两个解决方案:

方案一  对分配内存的操作进行同步处理——实际上虚拟机采用CAS配上失败重试的方式保证更新操作的原子性。

方案二  把分配内存的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)。哪个线程要分配内存,就在哪个线程的TLAB上分配,只有TLAB用完并需要分配新的TLAB的时候,才需要进行同步锁定。虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB参数来设定。

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头,因为对象头中要保存其他信息),如果使用TLAB,这一工作可以提前至TLAB分配的时候进行。这一操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

接下来,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头(Object Header)之中。根据虚拟机当前运行状体的不同,如是否启动偏向锁等,对象头会有不同的设置方式。

上面的工作完成之后,从虚拟机的视角来看,一个新的对象就已经产生了,但从Java程序的视角看,对象的创建才刚刚开始——<init>方法还没有执行,所有的字段还是零值。所以,一般来说(由字节码中是否跟随invoke special指令所决定),执行new指令之后会接着执行<init>方法,把对象按照程序员的意愿进行初始化,这样一个真正的对象才算产生出来了。

总结对象的创建过程:

类加载检查→对象内存分配→各字段赋零值→对象头信息设置→初始化

HotSpot虚拟机对象创建的更多相关文章

  1. HotSpot虚拟机对象相关内容

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

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

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

  3. 深入理解JVM(③)——之HotSpot虚拟机对象探秘

    前言 上篇文章介绍了Java虚拟机的运行时数据区域,大致明白了Java虚拟机内存模型的概况,下面就基于实用优先的原则,以最常用的虚拟机HotSpot和最常用的内存区域Java堆为例,升入探讨一下Hot ...

  4. HotSpot虚拟机对象探秘(对象创建,对象内存布局,对象访问定位)

    以常用的HotSpot虚拟机和JAVA内存区域堆为例,探讨对象的创建,对象的内存布局以及对象的访问定位 一.对象的创建 1)类加载:虚拟机遇到一条new指令时,先检测这个指令的参数能否在常量池中定位到 ...

  5. 深入理解java虚拟机(二)HotSpot Java对象创建,内存布局以及访问方式

    内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的 ...

  6. HotSpot虚拟机对象探秘-笔记

    学习目的:探讨HotSpot虚拟机在Java堆中对象分配.布局和访问的全过程. 1.对象的创建 虚拟机在执行到一条new指令时,先要检查指令的参数(将要实例化的类)是否已经被加载.解析.初始化过,如果 ...

  7. HotSpot 虚拟机对象揭秘【转载】

    对象的创建 Java 对象的创建过程, ①类加载检查: 虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过.解 ...

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

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

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

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

随机推荐

  1. 通过例子进阶学习C++(四)计算2的64次方,不服写写看

    ​ 本文是通过例子学习C++的第四篇,通过这个例子可以快速入门c++相关的语法. 1.乍一看题目非常简单,简单思考一下,可以通过for循环实现: #include <iostream> u ...

  2. 通过自己实现接口来加深理解SpringMVC的执行流程

    功能介绍 上篇文章[从源码角度了解SpringMVC的执行流程]通过接口源码向大家介绍了SpringMVC的执行流程,主要偏重于源码.这篇文件我们来自己实现那几个关键接口,来真实体验下SpringMV ...

  3. 自媒体工具OpenWrite

    自媒体工具OpenWrite  本篇主要介绍一款自媒体工具OpenWrite,如果你平时喜欢写写文章又或者写写笔记 你可以使用OpenWrite 统一将你写的文章发布到各个平台 包括 CSDN . S ...

  4. dfs 序 欧拉序

    推荐博客 :https://www.cnblogs.com/stxy-ferryman/p/7741970.html DFS序其实就是一棵树顺次访问的结点的顺序,例如下面这棵树 它的 dfs 序就是 ...

  5. 机器学习-特征工程-Feature generation 和 Feature selection

    概述:上节咱们说了特征工程是机器学习的一个核心内容.然后咱们已经学习了特征工程中的基础内容,分别是missing value handling和categorical data encoding的一些 ...

  6. Java入门 - 语言基础 - 16.数组

    原文地址:http://www.work100.net/training/java-array.html 更多教程:光束云 - 免费课程 数组 序号 文内章节 视频 1 概述 2 声明数组变量 3 创 ...

  7. 异数OS-织梦师-异数OS虚拟容器交换机(七) 走进4Tbps网络应用时代,加速5G应用真正落地

    . 异数OS-织梦师-异数OS虚拟容器交换机(七) 走进4Tbps网络应用时代,加速5G应用真正落地 本文来自异数OS社区 github: https://github.com/yds086/Here ...

  8. 从0到1掌握某Json-TemplatesImpl链与ysoserial-jdk7u21的前因后果

    本文首发于先知社区: https://xz.aliyun.com/t/7096 前言 作为一名安全研究人员(java安全菜鸡),知道拿到exp怎么打还不够,还得进一步分析exp构造原理与漏洞原理才行. ...

  9. selenium之窗口滚动

    在这里和大家分享一下,selenium里面常用于处理窗口滚动的方法. location_once_scrolled_into_view 一般用于定位窗口底部元素.将窗口拉到最底部. window.sc ...

  10. kuangbin专题专题十一 网络流 POJ 3436 ACM Computer Factory

    题目链接:https://vjudge.net/problem/POJ-3436 Sample input 1 3 4 15 0 0 0 0 1 0 10 0 0 0 0 1 1 30 0 1 2 1 ...