A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 小鲁哥哥 于 2017-6-25 11:00 编辑

【济南中心】JVM高级特性二、JVM在堆中对象的分配、布局、访问过程
前面介绍了jvm运行时数据区域后,下面讲解下对内存中数据的其他细节,看他们是如何创建、布局及访问的
  一、对象的创建
   1.对象的分配
对象的创建分配方式主要有两种:指针碰撞和空闲列表
   指针碰撞:  
     假设堆内存中是绝对规整的,那么,在为新对象分配内存空间时,只需要将指针向空闲空间方向移动新对象
   所需大小的一段出来即可。
     一般使用带有compact(整理)过程的收集器时,使用指针碰撞
   空闲列表:
     如果内存不是规整的,这时就需要维护一个列表,记录哪些内存是空闲的,在分配空间时,从列表中找出一块
   足够大的空间划分为对象实例并更新列表记录
   使用基于mark-sweep算法的收集器时,使用空闲列表
   2.对象的初始化及设置
      初始化:内存分配完成后就是对对象进行初始化,虚拟机将初始化的内存空间都初始化为0值,
      这就是为什么对象的实例字段在java代码中不需要初始化也可以使用
      设置:之后,虚拟机对对象进行一些必要设置,主要是往对象头中存入类的元数据信息、对象的哈希值、分代年龄等。
      init: 经过上面两步后对象创建完成,但所有字段还都是0值。最后就是执行init方法,按程序员的意思初始化对象
      完成上述三步后,一个对象就算创建完成。
   二、对象的内存布局
 对象在内存中存储的布局主要分为三部分,对象头、实例数据、对齐填充
     对象头:
       对象头在对象设置阶段提到过,即在设置阶段会向对象头中存入一些类的元数据信息、哈希值、分代年龄等
       对象中主要分为两部分:运行时数据和类型指针
         运行时数据:主要存储上面对象设置阶段存储的哈希码、分代信息、锁状态标识、线程持有的锁等。
         类型指针:主要存储对象的类元数据的指针,即这个对象是哪个类的实例,此外,如果对象类型是数组,
         对象头中还会存储一个代表数据长度的数据
         对齐填充:不是必然存在的,在Hotspot中,要求对象起始地址必须是8字节的倍数,
         当对象实例部分没对齐时,用对齐填充来补全。
   三、对象的访问定位
java程序是通过栈上的reference数据来操作对象实例的,因此它只是一个引用,具体定位方式jvm有不同实现
     主流实现方式有两种:使用句柄和直接指针
     句柄池:
       原理:java堆中会划出一片区域作为句柄池,reference存储的就是句柄地址,
          里面包含对象实例数据的指针和对象类型指针
       好处:如果对象被移动,只需改变句柄池中存储的地址
     直接指针
       原理:如果使用的是直接指针,那么reference中存储的就是对象的地址
       好处:省去了一次定位的时间,效率更高
     Hotspot使用的是直接指针方式

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马