关于java:JVM系列4内存模型

7次阅读

共计 2214 个字符,预计需要花费 6 分钟才能阅读完成。

JVM 系列笔记目录

  • 虚拟机的根底概念
  • class 文件构造
  • class 文件加载过程
  • jvm 内存模型
  • JVM 罕用指令
  • GC 与调优

硬件层数据一致性

– 存储器层次结构

从 L6-L0 空间由大变小,速度由慢到快。

- 缓存一致性算法

CPU 实现缓存一致性的协定很多,其中 intel 应用的 MESI(Modified Exclusive Shared Or Invalid) 协定。具体能够参考:[MESI–CPU 缓存一致性协定](https://www.cnblogs.com/z0037…

古代 CPU 的数据一致性实现 = 缓存锁 (MESI…) + 总线锁

- 缓存行

缓存读取时的单位,个别是 64Byte
应用缓存行的对齐可能提高效率

- 伪共享

位于同一缓存行的 2 个不同的数据,被 2 个不同的 CPU 锁定,产生相互影响的伪共享问题。

如何解决?应用缓存行的对齐可能提高效率

CPU 乱序问题

– 概念

CPU 为了进步执行效率,会在一条指令执行的过程中 (比方去内存取数据 ( 慢 100 倍)),去同时执行另一条指令,前提是两条指令没有依赖关系。具体参考:[古代 cpu 的合并写技术对程序的影响](https://www.cnblogs.com/liush…

- 合并写

CPU 上有一个 WriteCombinBuffer,仅 4 个字节,比 L1 等级还高,某些写操作会合并在一起提交。[古代 cpu 的合并写技术对程序的影响](https://www.cnblogs.com/liush…

- 乱序证实

CPU 乱序景象有大佬写程序模仿进去了,具体参考:Memory Reordering Caught in the Act

如何保障在特定状况下保障不乱序

硬件级别

X86 CPU 级别内存屏障

sfence
    store fence 在 sfence 指令前的写操作必须在 sfence 指令后的写操作前实现
    
lfence
    load fence 在 lfence 指令前的读操作必须在 lfence 指令后的读操作前实现
    
mfence
    mixed fence 在 mfence 指令前的读写操作必须在 mfence 指令后的读写操作前实现

CPU 原子指令

 如 x86 上的”lock …”指令是一个 Full Barrier,执行时会锁住内存子系统来确保执行程序,甚至跨多个 CPU

总结:Software Locks 通常应用了内存屏障或原子指令来实现变量可见性和放弃程序程序

JVM 级别

JSR113 标准规定了 4 种内存屏障

LoadLoad 屏障
    对于语句 Load1;LoadLoad;Load2,在 Load2 及后续读取指令要读取的数据被拜访前,保障 Load1 要读取的数据被读取结束
    
StoreStore 屏障
    对于语句 Store1;StoreStore;Store2, 在 Store2 及后续写操作执行前,保障 Store1 的写入操作对其它处理器可见
    
LoadStore 屏障
    对于语句 Load1;StoreStore;Store2, 在 Store2 及后续写操作被刷出前,保障 Load1 要读取的数据被读取结束
    
StoreLoad 屏障
    对于语句 Store1;StoreStore;Load2, 在 Load2 及后续读取指令要执行前,保障 Store1 的写入操作对其它处理器可见 

sychronized/volatile 在字节码、JVM、硬件 OS 层面实现细节

– sychronized

  • 字节码层面

    sychronized m() : AccessFlag : ACC_VOLATILE

    sychronized(this){} : monitorenter monitorexit monitorenter

  • JVM 层面

    C/C++ 调用操作系统的同步操作

  • 硬件 OS 层面

    X86 : lock cmpxchg / xxx

-volatile

  • 字节码层面
    AccessFlag : ACC_VOLATILE
  • JVM 层面

    volatile 内存区域都加屏障

    StoreStoreBarrier volatile 写操作 StoreLoadBarrier

​ LoadLoadBarrier ​ volatile 读操作 ​ LoadStoreBarrier

  • 硬件 OS 层面

    windows lock 指令实现 或是 MESI 实现

面试 new Object() 6 连问

  • 1. 解释对象的创立过程

    该问题联合上篇博客:JVM 系列【3】Class 文件加载过程不难答复进去。

    class loading

    class linking (vertification prepraration resolution)

    class initiazing

    new 申请内存空间

    成员变量赋初始值

    调用构造方法 <init>: 成员变量赋初始值;执行构造方法语句,super() 父类结构。

  • 2. 对象在内存中的存储布局

    对象在内存中布局分一般对象和数组对象。

    一般对象 4 局部:对象头 markword(8 字节)、ClassPointer 指针 (4 或 8 字节)、实例数据、padding 对齐为 8 的倍数。

    数组对象 5 局部,和一般对象相似,但两头是数组长度 4 字节和具体的数组数据。

  • 3. 对象头具体包含什么

    对象头 markword(8 字节) 具体内容和对象锁状态有关系,其中最高位 2 位是锁状态中,最低 3 位用作锁标记位,两头 4 位是 GC 年龄,如下。

  • 4. 对象怎么定位

    通过句柄池和间接指针,具体参考:拜访对象两种形式 – 句柄和间接指针

  • 5. 对象怎么调配?

    对象的调配其实和垃圾回收 GC 有关系,后续总结 GC 具体讲。

  • 6.Object o = new Object() 在内存中的占用多少个字节

    16 个字节,依据第 2 点的内存布局能够算出。

常识分享,转载请注明出处。学无先后,达者为先!

正文完
 0