zoukankan      html  css  js  c++  java
  • JVM理论:(一/1)对象的创建过程

    一、对象的创建

    1、当虚拟机遇到一条new指令时,会先检查常量池中能否定位到这个类的符号引用,然后检查这个符号引用代表的类是否被加载、解析、初始化过。

    2、如果类还未加载过,要先执行类加载过程,静态变量此时会有一个系统初始值。

    3、类加载检查通过后,为新生对象在堆中分配内存,对象所需内存大小在类加载完后可完全确定。

    为对象分配内存有两种方法:

      指针碰撞 —— 如果java堆内存绝对规整,用过的内存在一边,空闲的内存都在另一边,中间放一个指针作为分界点,分配时把指针往空闲空间一端移动与对象大小相等的距离。(Serial、ParNew等带Mark-Compact标记整理

      空闲列表 —— java堆不规整,虚拟机维护一个列表,记录哪些内存块可用,分配时从列表中找到一块足够大的空间划分给对象实例,并更新列表记录。(CMS基于Mark-Sweep——标记清除

    为对象分配内存时要注意线程安全问题:

       解决对象创建时线程不安全的问题有两种方案,一种是对分配内存空间的动作进行同步处理——CAS配上失败重试;

      一种是使用TLAB让每个线程在java堆中先预留一小块内存-XX:+/-UseTLAB参数控制是否开启

    4、分配完空间后,为分配的内存空间初始化零值(不包括对象头),保证对象的实例字段在java代码中可以不附初始值直接使用。这个阶段是虚拟机对对象的初始化,成员变量此时会有一个系统初始值。

    5、对象头设置

      对象头存储“对象是哪个类的实例,如何才能找到类的元数据信息,对象哈希码、对象GC分代年龄等,是否使用偏向锁”等信息。

    6、执行<init>方法,这个阶段才把对象按程序员的意愿进行初始化。

    二、对象的内存布局

      对象是存在堆中的,那么对象的结构又是如何的呢?对象在内存中存储的布局可分为3部分:对象头、实例数据、对齐填充。

    1、对象头

    (1)对象头第一部分是“Mark Word”,以复用自身存储空间的方式存储对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。

      结构如下图,以第一行为例,在32位的HotSpot虚拟机中,如果对象是无锁的状态,那么这时“Mark Word”的32bit空间中的25bit就用于存对象的哈希码,4bit用于存对象分代年龄,2bit用于存锁标志位,1bit固定为0。

      

    (2)对象头的另一部分是类型指针,能通过这个指针来确定该对象是哪个类的实例,即指向方法区中类数据的指针。但不是所有虚拟机都将类型指针保留在对象数据上,结合句柄、直接指针两种方式。

    (3)如果对象是数组,对象头还要有一块记录数组长度的数据。

     2、实例数据

       对象真正存储的有效信息,包括存从父类继承下来或在子类中定义的各种类型的字段内容,这部分存储顺序会受虚拟机分配策略参数(FieldsAllocationStyle)和字段在源码中定义顺序的影响。

    3、对齐填充部分

      起占位符的作用,保证对象的大小必须是8字节的整数倍。

    三、对象的访问

      建立对象后,需要通过栈上的reference数据去定位堆中对象的具体位置,有句柄和直接指针两种方式。

    (1)句柄:若使用句柄方式,java堆中会划分出一块内存作为句柄池,reference存的是对象的句柄地址,句柄存的是实例数据与类型数据的地址。

        

    (2)直接指针:若使用这种方式reference中存的直接就是对象地址,并且对象的结构里就要考虑如何放置类型指针的相关信息。

       

    对比来说,句柄的好处是,reference中存储的是稳定的句柄地址,对象被移动时只会改变句柄中的实例数据指针,reference本身不需要修改。

           直接指针的好处是,速度快,节省了一次指针定位的时间开销,HotSpot采用的是直接指针的方式。

  • 相关阅读:
    1451. Rearrange Words in a Sentence
    1450. Number of Students Doing Homework at a Given Time
    1452. People Whose List of Favorite Companies Is Not a Subset of Another List
    1447. Simplified Fractions
    1446. Consecutive Characters
    1448. Count Good Nodes in Binary Tree
    709. To Lower Case
    211. Add and Search Word
    918. Maximum Sum Circular Subarray
    lua 时间戳和时间互转
  • 原文地址:https://www.cnblogs.com/zjxiang/p/9211738.html
Copyright © 2011-2022 走看看