精华内容
下载资源
问答
  • JVM创建对象过程

    2019-07-21 14:56:26
    JVM创建对象过程如下:

    JVM创建对象的过程如下:
    在这里插入图片描述

    展开全文
  • JVM对象创建过程

    2019-10-09 15:32:59
    上一节我们讨论了jvm的类加载过程,这一节我们学习一下对象创建过程。 判断对象是否初始化,执行类加载 总所周知,一个对象被创建之前,必须要进行初始化,所有类加载过程是在对象创建过程之前完成的。 即如果...

    上一节我们讨论了jvm的类加载过程,这一节我们学习一下对象的创建过程。

    判断对象是否初始化,执行类加载
    总所周知,在一个对象被创建之前,必须要进行初始化,所有类加载过程是在对象创建过程之前完成的。
    即如果我们用new来创建一个对象,如果类还未被加载的话,会先加载该类,再进行对象的创建。

    为对象在堆上分配内存。

    分配内存主要有两种方式,指针碰撞和空闲列表。这个主要取决虚拟机的gc是否具有压缩整理的功能

    指针碰撞:假如内存空间是完整的,在空闲内存和已用内存中间有一个内存指针,当分配新的对象内存时,指针向空闲内存区移动新对象内存大小的距离
    空闲列表:当内存空间不是完整的,所有空闲内存保存在列表里,当新对象分配内存时,在空闲列表选取合适的内存大小,然后更新空闲列表信息。

    防止并发
    在虚拟机上创建对象是非常频繁的事,所以可能出现并发问题。jvm提供两种方式来防止并发

    1 堆内存分配空间实现同步处理,jvm通过cas和失败重试来保证更新操作的原子性。
    2 把内存分配的动作按照线程来划分为不同的空间,一开始为每个线程提供堆中的一小块内存,称为线程分配缓冲区tlab,当tlab用完时需要分配新的tlab时才进行同步锁定。

    初始化对象的内存空间
    内存分配完成后,jvm将分配到的内存空间都初始化为零值。

    对象头的设置
    将对象的类,hash码,及分代年龄放入对象头中

    执行java的init方法
    在jvm角度看。设置对象头完成后,对象创建完了,但是在java程序来看,必须执行完init方法和构造函数后才算创建完。

    对象的内存布局
    对象的内存自己是如何布局的呢,主要分为三部分

    • 对象头:
      对象头分为两部分,第一部分存储自身运行时数据,如哈希码,gc分代年龄,锁状态标志,线程持有锁,
      偏向时间戳,偏向时间Id
      第二部分是类型指针,对象指向类元数据的指针,确定是哪个类对象。
    • 实例数据:保存对象中各类型的字段内容
    • 对齐填充:当实例数据部分没有对齐,会进行对齐补全。

    对象的访问定位
    java通过栈上的引用类型reference数据来访问堆中的对象,主要的两种方式是通过句柄访问和直接指针。

    使用句柄:
    如果采用句柄访问,堆中会划分一段区域作为句柄区,而reference则保存句柄的地址,句柄保存对象的实例数据与类型数据各自的地址。
    在这里插入图片描述
    直接指针:
    栈中的referrence直接指向存储对象实例数据的地址。对象实例数据中包含对象类型数据的指针。
    在这里插入图片描述
    hotspot使用的是指针对象访问

    展开全文
  • JVM(二)JVM 创建对象过程分析

    千次阅读 2018-01-19 11:15:11
    首先来看一下JVM创建对象时的流程图: Created with Raphaël 2.1.2开始JVM 执行 new 指令类已加载?为新生对象分配内存内存规整?指针碰撞并发处理:同步或TLAB将分配到的内存空间初始化为零值JVM

    在语言层面上,创建对象通常仅仅是一个new关键字而已,而在虚拟机中,对象(文中讨论的对象限于普通Java对象,不包括数组和Class对象等)的创建又是怎样一个过程呢?首先来看一下JVM创建对象时的流程图:

    Created with Raphaël 2.1.2 开始 JVM 执行 new 指令 类已加载? 为新生对象分配内存 内存规整? 指针碰撞 并发处理:同步或TLAB 将分配到的内存空间初始化为零值 JVM 对对象进行设置 结束 空闲列表 执行类加载过程 yes no yes no

    接下来对上面的流程图进行一个大概的说明。

    一、类加载检查

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

    二、分配内存

    分配内存时主要注意两个问题:1.如何分配空间。2.修改指针时如何实现线程安全。

    2.1 分配内存

    内存的分配存在两种实现方式:

    • 指针碰撞:假设Java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”(Bump the Pointer)。
    • 空闲列表:如果Java堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”(Free List)。选择哪种分配方
    2.2 线程安全

    保证修改指针时线程安全也存在两种实现方式:

    • 同步处理:对分配内存的空间动作进行同步处理(采用CAS配上失败重试的方式保证跟新操作的原子性);
    • 本地线程分配缓冲:把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存,叫本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),哪个线程需要分配内存,就在那个线程的TLAB上分配,只有TLAB用完并分配新的TLAB时,才需要同步锁定。

    三、初始化和设置

    内存分配完成后,虚拟机将分配到的内存初始化为零值(除对象头外),如果使用TLAB分配,也可提前值TLAB分配时进行。

    接下来,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头(Object Header)之中。

    在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了,但从Java程序的视角来看,,对象创建才刚刚开始——<init>方法还没有执行,所有的字段都还为零。所以,一般来说执行new指令之后会接着执行<init>方法,把对象按照程序员的意愿进往初始化,这样一个真正可用的对象才算完全产生出来。

    展开全文
  • JVM 对象创建过程

    2020-09-04 14:21:31
    对象创建流程步骤包括哪些 虚拟机遇到一条new指令时,首先检查这个对应的类能否常量池中定位到一个类的符号引用 判断这个类是否已被加载、解析和初始化 为这个新生对象在Java堆中分配内存空间 Java堆分配...

    对象创建的流程步骤包括哪些

    对象创建底层的顺序.png

    • 虚拟机遇到一条new指令时,首先检查这个对应的类能否在常量池中定位到一个类的符号引用
    • 判断这个类是否已被加载、解析和初始化
    • 为这个新生对象在Java堆中分配内存空间

    Java堆分配内存空间的方式主要有以下两种

    对象分配.png

    指针碰撞

    • 分配内存空间包括开辟一块内存和移动指针两个步骤
    • 非原子步骤可能出现并发问题,Java虚拟机采用CAS配上失败重试的方式保证更新操作的原子性

    空闲列表

    • 分配内存空间包括开辟一块内存和修改空闲列表两个步骤
    • 非原子步骤可能出现并发问题,Java虚拟机采用CAS配上失败重试的方式保证更新操作的原子性
    • 将分配到的内存空间都初始化为零值

    • 设置对象头相关数据

    • GC分代年龄
    • 对象的哈希码 hashCode
    • 元数据信息
    • 执行对象<init>方法

     

    对象的数据结构

    对象内存布局.png

    • 对象头
      1)对象头用于存储对象的元数据信息,包括对象运行时数据和类型指针
      2)Mark Word 部分数据的长度在32位和64位虚拟机(未开启压缩指针)中分别为32bit64bit,存储对象自身的运行时数据如哈希值等。Mark Word一般被设计为非固定的数据结构,以便存储更多的数据信息和复用自己的存储空间
      3)类型指针:指向它的类元数据的指针,用于判断对象属于哪个类的实例

    • 实例数据存储的是真正有效数据,如各种字段内容,各字段的分配策略为longs/doubles、ints、shorts/chars、bytes/boolean、oops(ordinary object pointers),相同宽度的字段总是被分配到一起,便于之后取数据。父类定义的变量会出现在子类定义的变量的前面

    • 对齐填充部分仅仅起到占位符的作用

    对象访问的定位方式

    当我们在堆上创建一个对象实例后,就要通过虚拟机栈中的reference类型数据来操作堆上的对象

    现在主流访问方式有两种(HotSpot虚拟机采用的是第二种

    1. 使用句柄访问对象。即reference中存储的是对象句柄的地址,而句柄中包含了对象实例数据与类型数据的具体地址信息,相当于二级指针

    对象句柄访问.png

    2.直接指针访问对象。即reference中存储的就是对象地址,相当于一级指针

    直接指针访问对象.png

    对比

    垃圾回收方式分析

    方式1当垃圾回收移动对象时,reference中存储的地址是稳定的地址,不需要修改,仅需要修改对象句柄的地址;
    方式2垃圾回收时需要修改reference中存储的地址

    访问效率分析

    方式2优于方式1,因为方式2只进行了一次指针定位,节省了时间开销,而这也是HotSpot采用的实现方式

    展开全文
  • java是一门面向对象的语言,java程序运行过程中无时无刻都有对象创建出来。语言层面上,创建对象(克隆,反序列化)就是一个new关键字而已,但是虚拟机层面上却大不相同。 虚拟机创建对象的步骤: 虚拟机遇到一条...
  • 2.类加载通过之后,虚拟机将为新生对象分配内存。 3.虚拟机将分配到的内存空间都初始化为零值(不包括对象头)。 4.接下来虚拟机要对对象进行一系列的设置,例如:对象是哪个类的实例、对象的哈希码等等。 5....
  • JVM创建对象过程简介

    2018-12-13 17:23:26
     Java程序运行时无时无刻都有对象创建出来,语言层面上,创建对象只是通过一个new关键字,那么在JVM对象是如何被创建出来的? JVM解析到new指令时,会去常量池中(方法区里面)定位该类的符号引用,并且检查...
  • 下面我们详细了解Java程序中new一个普通对象时,HotSpot虚拟机是怎么样创建这个对象的,包括5个步骤:相应类加载检查过程Java堆中为对象分配内存、分配后内存初始化为零、对对象进行必要的设置、以及执行对象...
  • new对象的时候,jvm中的具体执行过程如下: 类加载检查.在创建对象前,jvm会检查该类是否已经被加载虚拟机中,如果没有的话就会去执行类加载;待类加载完成后才会内存中创建这个对象的空间.原因是,每一个对象在...
  • JVM 创建 Java 对象

    2019-06-25 10:53:25
    JVM 创建 Java 对象流程:类的加载,内存分配、对对象进行必要的设置、执行 <init> 方法初始化。 1.JVM 创建 Java 对象 使用 new 关键字可以创建一个类的对象。 new指令虚拟机中的执行操作: 类的...
  • JVM对象创建流程

    千次阅读 2017-12-21 19:32:37
    java是一门面向对象的编程语言,java程序运行过程中无时无刻都有对象创建出来。语言层面上,创建对象(例如克隆,反序列化)通常仅仅是一个new关键字而已,而虚拟机中,对象(限于普通java对象,不包
  • JVM对象创建流程解析

    2018-10-19 11:48:44
    jvm创建对象的第二步就是划分这块空间的,划分空间还有讲究,有两种方式,第一种是如果java堆是连续分配的,那么我们已经分配给实例对象的堆空间和还空着未分配给实例对象的堆空间之间有一个分界线,我们用指针...
  • jvm对象创建过程

    千次阅读 2014-04-30 10:04:05
    2虚拟机为新生对象分配内存,分配方式有指针碰撞,空闲列表.(这里对象创建是非常频繁的,需要考虑原子性问题)3内存分配后,jvm要将分配到的内存初始化为零值。4jvm对象进行必要的设置,入对象是哪个类的,对象的...
  • jvm 创建对象过程

    2020-09-09 14:46:27
    exg: 1 2 3 4 5
  • JVM——对象创建过程

    千次阅读 2018-03-23 20:11:51
    对象创建过程:我们Java代码中new 一个对象时,我们很难看到对象创建的过程,尤其是在jvm内存中的过程,下面来介绍一下对象创建在jvm中的过程: 对象实例在jvm中是存在于java堆中的,每一个对象实例都会占用...
  • JVM对象创建

    2018-03-25 20:01:49
  • 文章目录JVM创建内存时的内存分配过程分析当jvm遇到一条new()指令时,从开始到堆内存中生成执行之间发生了什么一、对象创建过程分析二、创建过程详细分析1.加载类2.给对象分配内存3.初始化4.设置对象头5.执行 ...
  • 对象创建过程 class loading 加载class到内存汇总 class linking verification 校验是否语句满足JVM规范 preparation 初始化提供默认值 resolution class解析 class initializing 提供初始值 申请对象内存 ...
  •  下面我们详细了解Java程序中new一个普通对象时,HotSpot虚拟机是怎么样创建这个对象的,包括5个步骤:相应类加载检查过程Java堆中为对象分配内存、分配后内存初始化为零、对对象进行必要的设置、以及执行对象...
  • java是一门面向对象的编程语言,程序运行过程中无时无刻都有对象创建。对于语言层面来说,创建对象通过new关键字就可以实现,但在JVM层面上伴随着以下的复杂过程
  • JVM对象创建过程

    2017-06-23 23:22:02
    这个创建对象过程中,JVM做了不少的工作,流程大体如下: Created with Raphaël 2.1.2Startnew 指令定位类引用,是否被加载?分配内存并初始化零值按java代码进行初始化End执行类加载yesno 定位符号引用 ...
  • 文章目录JVM笔记二:对象对象创建对象的内存布局访问对象过程 对象创建 java对象创建底层执行图 创建对象流程 1、虚拟机遇到一个new指令时,首先检查这个对应的类能否常量池中定位到一个类的符号引用。 ...
  • JVM 知识点整理:对象创建过程类加载分配内存分配方式一:指针碰撞分配方式二:空闲列表如何选择?线程安全问题CAS + 失败重试方法线程本地分配缓存区(TLAB)后续工作 类加载 虚拟机遇到一条 new 指令时,首先...
  • JVM 类加载机制、对象创建过程

    千次阅读 2020-06-03 11:48:51
    目录类加载的过程类加载器类加载机制类加载时机类加载方式对象创建过程对象的内存布局对象的访问方式   类加载:jvm读取.class文件,解析获取类的信息,生成对应的Class对象。   类加载的过程 主要分为...
  • JVM】Java对象创建过程

    千次阅读 2021-05-08 16:36:23
    对象所需内存大小类加载完成后即可确定,从Java堆中划分一块确定大小的内存。 内存分配的两种方式: 2.1 指针碰撞 适用场合:堆内存规整 原理:用过的内存放一边,没用过的放另一边,中间有一个分界值指针。向着...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 244,392
精华内容 97,756
关键字:

对象在jvm的创建过程