Java虚拟机学习(三)

对象的建立

HotSpot虚拟机中,当咱们使用new关键字建立一个对象的时候,虚拟机会作以下的操做:数组

  1. 查看方法区中的常量池是否能定位到对象类的符号引用,而且检查这个引用是否被加载过、解析和初始化过,若是没有,将先执行类加载;
  2. 为对象分配内存空间;
  3. 设置对象头;
  4. 执行数据初始化;

为对象分配内存空间可能有两种方式:安全

  1. 指针碰撞(Bump the pointer):当内存是绝对规整时,按内存的连续性分配内存,以一个指针标记当前已用内存和空闲内存的边界
  2. 空闲列表(Free List):当内存不规整时,虚拟机须要维护一张列表,记录哪些内存可用

内存是否规整取决于所采用的垃圾回收器,在内存分配时还须要考虑线程安全问题,解决方案有:布局

  1. 对分配内存的动做进行同步处理;
  2. 把内存分配的动做按照线程划分红不一样的空间中进行,每一个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer, TLAB),能够用参数-XX:+UseTLAB启用

对象的内存布局

  1. 对象头(Header):分为两部分,第一部分用于存储对象运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,官方叫作Mark Word;另外一部分是类型指针,即对象指向它的类型数据的指针;另外若是是一个数组对象,对象头中还必须有数组的长度;
  2. 实例数据(Instance Data)
  3. 对齐填充(Padding)

对象的访问定位

目前主流的访问方式有使用句柄和直接指针:spa

  1. 使用句柄:将在Java堆中划分出一块内存来做为句柄池,引用中存放的就是句柄的位置,句柄中存储了对象的类型指针和对象地址的指针;优点:当垃圾回收时,对象可能被移动,自动后只须要修改句柄中的地址
  2. 直接指针:引用中直接放的对象的地址,对象的类型经过对象头信息找到;优点:速度更快,节约了一次指针定位的时间
相关文章
相关标签/搜索