JVM①Loading&JMM

文章目录

    • class文件的加载过程
    • java内存模型 JMM
    • 乱序问题
    • 对象内存布局
      • 对象创建过程
      • 对象在内存中的存储布局

class文件的加载过程

  • loading

    1. 加载层次 低 --> 高
      Custom ClassLoader --> App --> Extension --> Bootstrap
    2. 双亲委派 – 防止内部类被覆盖
      低 -> 高,依次在缓存中寻找需要加载的类,有就直接返回;都无,高 -> 低,依次加载类,若都失败,抛出 ClassNotFoundException。
    3. 自定义类加载器
      1. 继承ClassLoader
      2. 重写模板方法findClass
  • linking

    1. verification :校验文件是否符合JVM规范
    2. preparation给静态变量赋初始值
    3. resolution :解析,将常量池符号引用转为内存地址
  • initializing :静态变量赋值

java内存模型 JMM

  • cpu运行速度 高 -> 低
    • L0(寄存器) > L1 > L2 > L3(所有cpu共享)
  • cache line
    • MESI缓存一致性协议
      1. M :修改,本线程修改过
      2. E:独占,刚修改后为独占状态
      3. S:共享,与其他线程数据一致
      4. I:无效,一个线程改过后,其他线程此数据无效
    • cache line概念
      1. 读取缓存以 cache line 为单位,64个字节
    • false sharing(伪共享)
      1. 同一个cache line 中多个数据被不同的线程锁定,产生相互影响。
        • 例:cache line 中 A,B两个数据被线程A,线程B共享;线程A修改A数据,会导致线程B要重新去主存中加载cache line。
      2. 解决
        • 使用缓存行对齐,能提升一定的效率。

乱序问题

cpu为了提高指令的运行速度,会在执行一条指令的过程中,执行另一条指令(前提这两条指令没有依赖关系)。

如何保证指令的有序性

  1. 硬件内存屏障

sfence :写操作不可指令重排
lfence : 读操作不可指令重排
mfence :读写操作不可指令重排

  1. jvm级别规范

LoadLoad屏障 :指令前的读操作完毕才能执行指令后的读操作
StoreStore屏障:指令前的写入数据对其他处理器可见
LoadStore屏障:指令前的读操作完毕才能执行指令后面的写操作
StoreLoad屏障:指令前的写操作对其他处理器可见才能执行指令后的读操作

volatile实现细节

  1. 字节码层级 --> ACC_VOLATILE
  2. JVM层级 --> volatile读写都加屏障

StoreStore Barrier
volatile 写
StoreLoad Barrier

LoadLoad Barrier
volatile 读
LoadStore Barrier

  1. OS和硬件层级

windows lock 指令实现 | MESI实现

synchronized实现细节

  1. 字节码层级
    1. 方法:ACC_SYNCHRONIZED
    2. 同步代码块:monitorenter monitorexit
  2. JVM层级 --> C C++ 调用了操作系统提供的同步机制
  3. OS和硬件层级 --> lock cmpxchg / xxx

对象内存布局

对象创建过程

123将class文件load到内存,456初始化对象

  1. class loading
  2. class linking
    1. verification:校验是否符合JVM规范
    2. preparation:静态变量赋默认值
    3. resolution:解析,常量池符号引用转为地址引用
  3. initializing: 静态变量赋值,调用静态语句块
  4. 申请内存空间
  5. 成员变量赋默认值
  6. 调用构造方法
    1. 顺序给成员变量赋值
    2. 执行构造语句方法

对象在内存中的存储布局

观察虚拟机配置
java -XX:+PrintCommandLineFlags -version
JVM①Loading&JMM_第1张图片

  1. 普通对象
    1. markword (对象头) 8字节
    2. Classpointer(指针,指向类)
      1. 上图 1开启为4字节 不开启为8字节
    3. instance
      1. 数据为引用类型:上图 2开启为4字节,不开启为8字节
    4. padding 对齐,不足8的倍数自动补齐
  2. 数组对象
    比普通对象多出一个数组长度 --> 4字节

对象头 markword

  1. 1bit 表示是否为偏向锁,2bit 表示锁标志位
  2. 4bit 表示分代年龄
  3. 31bit 表示hashCode

GC最大年龄
markword只有4bit表示分代年龄,最大15

你可能感兴趣的:(JVM,知识)