2、虚拟机对象的建立

(一)对象建立的过程java

  1. 首先尝试在常量池中查找相应类的信息,若查不到则加载类
  2. 接下来为对象在堆中分配空间(对象分配的空间大小在类加载是已肯定),这里有两种分配方式:在虚拟机内存规整的时候使用指针碰撞(把指针向空闲空间挪动必定位置),在内存不规整时使用空闲类表(即维护一个列表,记录哪些空间是可用的,在分配时找一块足够大的内存分配给对象)
  3. 再分配空间是须要考虑并发问题,经常使用的处理方法有两种:第一种是采用CAS加失败重试的方法分配内存;第二种是为线程分配本身独有的本地缓冲(TLAB,这样只需在分配缓冲的时候须要处理并发,是否启用TLAB能够经过虚拟机参数设置)
  4. 接下来为对象设置对象头(Object Header),对象头中存储Hash码,年龄带等信息
  5. 虚拟机级别的对象建立完成

(二)对象在内存中的布局数组

  1. 对象在内存中储存的布局分三部分:对象头(存放Hash码、年龄带、锁状态标志等),实例数据(java类中的属性等),对其补充
  2. 对象头:对象头中除了存储上述信息,还有一部分是实例的类型指针(即虚拟机经过这个指针肯定对象是哪一个类的实例);若此对象是数组,那么还须要存储数组长度
  3. 实例数据:存储类中各个字段的值(不管是父类的仍是本身的),存储的顺序按照字段类型的宽度进行排序,可能子类宽度较窄的字段插在父类字段之间(能够经过CompactFields=false,使子类的字段必定排在父类后边)
  4. 对其补充:因为虚拟机自动内存管理系统要求,对象的起始地址必须为8的整数倍个字节,因此不是8的整数倍,须要补充,这个区域没有什么实际意义

(三)对象的访问并发

  1. 虚拟机访问对象有两种方式:使用句柄,直接指针
  2. 使用句柄:在java堆中划出一部分区域做为句柄池,reference中存的就是对象的句柄地址,句柄地址中包含指向实例数据的指针和指向类型数据的指针
  3. 直接指针:reference中存储的直接就是实例的地址,实例中存放指向类型数据的指针
  4. 使用句柄的好处在于当实例数据常常移动时(垃圾回收)只需改变句柄中实例数据的指针便可,而使用直接指针的好处在于速度快,在访问对象(java就是对于对象的操做)时节省了一次调用指针的开销
相关文章
相关标签/搜索