内存屏障与JVM指令:markword、对象创建过程、对象内存布局

JVM内存屏障

> LoadLoad屏障:

>      对于这样的语句

Load1;

LoadLoad;

Load2,
>
>      在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。

StoreStore屏障:
>      对于这样的语句

Store1;

StoreStore;

Store2;

>      在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。
>
> LoadStore屏障:
>
>      对于这样的语句

Load1;

LoadStore;

Store2;

>      在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。
>
> StoreLoad屏障:
>  对于这样的语句

Store1;

StoreLoad;

Load2;
>
> ​     在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。

volatile 底层实现:

字节码层面:

volatile 会编译成  ACC_VOLATILE

jvm层面

写操作:

StoreStoreBarrier

volatile 写操作

StoreLoadBarrier

读操作

LoadLoadBarrier

volatile读操作

LoadStoreBarrier

synchronized 底层

字节码层面 : monitorenter monitorexit

JVM层面: C C++ 调用了操作系统提供的同步机制

OS和硬件层面:X86(cpu)  lock comxchg / xxxx 指令

对象创建过程:

1.class loading   将对象load 到内存 ,例如 T()对象

2.class linking(verification, preparation, resolution)

  • 1. Verification
  •   验证文件是否符合JVM规定
  • 2. Preparation
  •   静态成员变量赋默认值
  • 3. Resolution
  •   将类、方法、属性等符号引用解析为直接引用
  •   常量池中的各种符号引用解析为指针、偏移量等内存地址的直接引用

3.class initializing  类的静态变量设为初始值,执行静态语块。

4.申请对象内存

5.成员变量赋默认值

6.调用构造方法<init> 1.成员变量顺序赋初始值 2.执行构造方法语句

对象在内存中的存储布局

普通对象

1. 对象头:markword  8字节。  标识着头对象的状态,被回收了多少次。
2. ClassPointer指针:-XX:+UseCompressedClassPointers 为4字节 不开启为8字节. 
      T t = new T();  t 里面的指针指向 t.class. 即该对象属于哪个class
3. 实例数据 : 成员变量
   1. 引用类型: 开启为4字节 不开启为8字节
      Oops Ordinary Object Pointers  开启: -XX:+UseCompressedOops
4. Padding对齐,8的倍数。  数据是一块一块读的,所以需要对齐。

 

Object o = new Object() 在内存中占用多少字节

未压缩:对象头 8字节+ 指针 8字节 + 对齐 8 字节 = 24 字节

压缩: 对象头8字节+ 指针4 字节 + 对齐 4  = 16 字节  (对齐为8 的倍数)

数组:   对象头8 字节 + 指针 8 字节(未压缩) +  对齐 4 字节+ 长度 4 字节 = 24 字节

 

数组对象:

1. 对象头:markword 8
2. ClassPointer指针同上
3. 数组长度:4字节
4. 数组数据
5. 对齐 8的倍数

markword  8个字节 + 8个 class point (64位) 。如果开启了指针压缩则是 : markword 8 + ClassPointer 4。 

头指针压缩: 8字节变4字节

不开启指针压缩参数:-XX:-UseCompressedClassPointers

开启指针压缩参数: -XX:+UseCompressedClassPointers

普通对象指针压缩: 8字节变4字节   Oops: Oops Ordinary Object Pointers

不开启:-XX:-UseCompressedOops

开启:-XX:-UseCompressedOops

对象头具体包括什么

32位

markword 64bit (8byte) : 3位锁标志, 4位分代年龄(GC标记,被回收了多少次), 25 位hashcode(没有重写过hashcode方法,默认使用的identityHashcode()生成的) 。

64位的 unused(未使用的) : 25位,hash: 31位。

对象定位

1.句柄池

2.直接指针

猜你喜欢

转载自blog.csdn.net/dandanforgetlove/article/details/106080956