1.概览

HotSpot是JAVA最流行,用的最多的虚拟机。一般我们说java虚拟机也都指的是HotSpot虚拟机。

2.使用new对象创建的过程

  1. 检查常量池能否找到
  2. 检查是否有必要加载类
  3. 指针碰撞——移动分界指针(该指针区分了空闲和非空闲内存)或者空闲列表——用列表来记录内存状态。不同收集器采用的方式不同
  4. 初始化值(可以再TLAB中提前准备好)
  5. 设置元数据、哈希码、分代信息等,保存到类头部 6.调用方法按照程序员的意愿初始化对象实例

优化:为了避免堆资源的竞争,可以在堆区域预留一块本地线程分配缓冲(TLAB),需要分配直接从这里面去,这样可以保证原子性。如果TLAB用完再考虑同步锁定。-XX:+/-UseTLAB设定

3. 对象的内存布局

在内存中分为三块区域:

  1. 对象头
  2. 实例数据
  3. 对齐填充

    3.1 对象头(Mark Word)

  4. 存储对象自身的运行时数据比如哈希码、GC分代年龄、锁状态标识等

  5. 类型指针:通过这个指针来确定这个对象是哪个类的实例

    3.2 实例数据

    存储的有效信息。存储顺序受到虚拟机分配策略参数和字段在JAVA源码中定义顺序的映像,默认分配的时候相同宽度的字段在一起,父类的在子类前面

3.3 对齐填充

VM要求对象其实地址必须是8字节的整数倍

4. 对象的访问定位

主要有两种方式:

  1. 堆中划分出一块内存作为句柄池,JAVA栈中存储对象的句柄地址,句柄地址包含对象实例数据和类型数据具体信息。优点:对象呗移动的时候只会改变句柄宏的实例指针,栈中的对象引用不用变化。
  2. 直接指针访问(spot vm的方式):优点是速度快,节约了一次指针定位的开销。