美文网首页
对象的创建

对象的创建

作者: 曾经不努力的人 | 来源:发表于2018-04-21 17:06 被阅读0次

对象的创建

    虚拟机遇到一条new指令时,首先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有那必须先执行类加载过程,类加载完成后会为新对象分配内存,对象所需的内存大小在类加载完成后已经确定,最后从Java堆中划出一段确定大小的内存。

    如果Java堆内存是规整的,一边区域是已分配的,一边区域是未分配的,那么可以通过移动指针完成内存的分配;如果Java堆内存是不规整的,那么Java虚拟机中需要维护一个内存可用的列表,然后从这个列表中选出一个足够大的内存片段进行分配,并更新列表记录。

    Java虚拟机创建对象是个很频繁的动作,在并发的情况下,即使移动一个指针也会涉及到线程安全的问题,有两种方法可以解决这个问题,一种是对内存分配的操作进行同步操作,另一种在Java堆中为每个线程分配一块内存,称为本地线程分配缓冲(TLAB)。哪个线程需要分配内存就在哪块TLAB上分配,当TLAB内存用完后,需要分配新的TLAB(这种情况下需要进行同步操作),通过-XX:+/-UseTLAB参数设置。

    内存分配完成后,虚拟机需要将分配的内存空间初始化为零值(不包括对象头)。这一步操作保证了对象的实例字段在Java代码中不赋值的情况下可以使用。

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

    上述这些步骤,从虚拟机的角度来看,一个对象已经产生了,但如果从Java程序来看,对象创建才刚刚开始,<init>方法还没执行,所有的字段都还是0。因此执行完new指令后会执行<init>方法,把对象按照程序员的意愿进行初始化。

对象的内存布局

    此处主要分析的是HotSpot虚拟机。

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

    对象头包括2部分信息:

    第一部分用于存储对象自身的运行时数据,包括哈希码(HashCode)、GC分代年龄、锁状态标识、线程持有的锁、偏向线程ID、偏向时间戳。

    第二部分是类型指针,对象指向它的类元数据的指针,即是这个对象是哪个类的实例。并不是所有的虚拟机实现都必须在对象数据中保留类型指针。如果对象是一个数组,还必须有一块用于记录数组长度的数据。因为普通对象可以通过元数据确定对象的大小,但数组中的元数据无法确定。

对象的访问定位

    建立对象是为了使用对象,Java程序中需要通过栈上的reference引用使用对象,但具体怎么使用需要根据虚拟机来确定。

    通过句柄池引用:Java堆中有一块区域存储对象实例数据的句柄池,reference存储的是对象的句柄地址,句柄中包含了对象实例数据和对象类型的指针。

    通过直接指针访问:reference存储是对象的实例,对象的实例数据中包含了对象类型的指针。

    使用第一种方式,当对象移动后,只需要改变句柄池中对象的引用,不需要改变reference;使用第二种方式,减少了指针定位。

相关文章

  • javascript面向对象解析(一)

    创建对象的方式 json对象方式创建对象 Object方式 声明构造函数方式,创建对象 -- 这种创建对象的方式用...

  • JS笔记-006-JS对象-数字-字符串-日期-数组-逻辑

    JS对象 创建 JavaScript 对象 通过 JavaScript,您能够定义并创建自己的对象。 创建新对象有...

  • 创建对象只是开辟个堆内存那么简单吗?

    java对象 对象的创建 java的对象是在运行时创建的,创建对象的的触发条件有以下几种: 用new语句创建对象,...

  • 对象的创建

    对象的创建 虚拟机遇到一条new指令时,首先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检...

  • 对象的创建

    一、创建过程 二、重点说明 1.在Java堆中为对象分配内存空间 分配方法 有两种主流方法:指针碰撞;空闲列表。 ...

  • 对象的创建

    创建对象1.工厂模式 2.构造函数模式 3.原型模式 4.组合使用原型模式和构造函数模式 (常见的方式) 5.动态...

  • 对象的创建

    工厂模式 优点:避免创建多个对象时的重复代码问题 缺点:无法解决对象识别问题(不知道一个对象的类型) 构造函数模式...

  • 对象的创建

    1.给对象分配内存 两种方式:1.指针碰撞 2.空闲列表 2.线程安全性问题 3.初始化对象 4.执行构造方法

  • 对象的创建

    1.OC对象是什么? 从源码分析 objc.h objc-private.h: 其中uintptr_t是一个uns...

  • 对象的创建

    JavaScript中的对象实际上是键值对的集合,如何去创建一个对象呢?有以下方法: 字面量创建(Object L...

网友评论

      本文标题:对象的创建

      本文链接:https://www.haomeiwen.com/subject/vtdxlftx.html