JVM学习笔记:对象的内存布局和访问定位

  对象内存布局:

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

  一、对象头包括两部分信息:

  第一部分用户存储对象自身的运行时数据、如哈希码、GC分代年龄、线程持有的锁、偏向线程ID,偏向时间戳等,官方称它为”Mark Word“

  第二部分用于存放类型指针,虚拟机可以通过这个指针来确定这个对象是哪个类的实例。另外,对象如果是一个java数组,那再对象头中还必须有一块用于记录数组长度的数据。因为虚拟机可以通过普通java对象的元数据确定java对象的大小,但是从数组的元数据中却无法确定数组的大小

  二、实例数据:

  实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的名称类型的字段内容。无论是从父类继承下来的,还是从子类中定义的,都需要记录下来。这部分的存储顺序会受到虚拟机分配参数和字段在java源码中定义顺序的影响。

  三、对齐填充:

  对齐填充并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。虚拟机的自动内存管理系统要求对象起始地址必须是8个字节的整数倍,因此党实例数据部分没有对齐时,就需要通过对齐填充来补全。

  备注:对象头正好是8字节的倍数,所以不会影响是否对齐填充。

  对象的访问定位:

  java程序需要通过栈上的reference(引用)数据来操作堆上的具体对象。对象的访问方式是取决于虚拟机实现决定的,目前主要的访问方式有使用句柄直接指针两种。

1)句柄访问:

  句柄访问最大的好处是reference中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针。

2)直接访问:

  使用直接指针访问方式最大的好处就是速度更快,它节省了一次指针定位的开销,由于对象的访问在java中非常频繁,因此这类开销积少成多后也是一项非常可观的执行成本。

  

  

  

  

  

posted on 2019-06-21 13:55  圆码  阅读(109)  评论(0)    收藏  举报

导航