Object对象详解

一 创建对象的过程

如果方法区中没有Class对象,需要先加载类

  • 1.class load
  • 2.class linking(verify, prepare, resolution)
  • 3.class initialization
  • 4.分配对象内存
  • 5.对象属性赋默认值
  • 6.执行方法

二 对象在内存中的存储布局

padding保证总字节数8的倍数

  • 普通对象
属性 mark word class pointer 实例数据 padding
占用字节 8 4 不定 不定
  • 数组对象
属性 mark word class pointer 数组长度 元素数据 padding
占用字节 8 4 4 不定 不定

注意

  • -XX:+UseCompressedClassPointers 为4字节 不开启为8字节
  • 引用类型:-XX:+UseCompressedOops 为4字节 不开启为8字节 Oops: Ordinary Object Pointers

对象头具体包括什么?

jvm源码位置:markOop.hpp
* 对象的内存分布

class A{
//  boolean flag = false;
}
public class SynchronizeStudy {

  public static void main(String[] args) {
    Object a = new A();
    System.out.println(ClassLayout.parseInstance(a).toPrintable());
  }
}

 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

小端序:数据的高位字节存放在地址的高端 低位字节存放在地址低端

对象怎么定位?

  • 句柄池
    定位对象耗时更长些,但对GC友好
    栈中reference存储的是稳定的句柄地址,在GC导致的对象移动时,只会改变句柄中的实例数据指针,而reference本身是不需要改变的。
  • 直接引用
    定位对象速度更快,节省了一次指针定位的时间开销。

对象怎么分配?

为了防止移动指针导致的并发,首先会在本地线程分配缓存(TLAB)分配内存。如果TLAB内存不足再使用CAS在堆上分配内存。

posted @ 2021-03-05 18:34  老汤的猫  阅读(51)  评论(0编辑  收藏  举报