我的JVM(四):JMM运行时内存结构

一、概述

    上一文我们主要分析了class文件的加载过程,那么本文主要来分析JMM内存模型,英文名JAVA Memory Model,它是与计算机硬件有关的一个概念。为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范。

二、解析

    1. 硬件层的并发优化基础知识

    存储器的层次结构图如下:

    

    各级缓存耗时对比:

    

    采用分层缓存的层次结构会带来数据不一致问题,如下图:

    

    那么如何保证数据的一致性,现代CPU处理办法有两种:

        (1) 锁系统总线;

        (2) 利用缓存一致性协议MESI(Intel处理器用的比较多,还有很多其他的缓存一致性协议),详细介绍请查看《我的并发编程(三):Volatile的底层实现及原理》(包括缓存行等概念知识),大致结构如下图:

    

    2. CPU的乱序执行

     CPU中有个乱序执行的概念,概念图如下:

    

    CPU在执行指令的时候,往往不是顺序执行,但是会遵守as-if-serial原则,也就是最终一致性原则。CPU为了提高指令执行效率,会在一条指令执行过程中(比如去内存读数据),去同时执行另一条指令,前提是这两条指令没有依赖关系。虽然指令执行顺序发生改变,但是不会影响单线程执行结果。多线程情况下为了不让CUP进行指令重排序,则需要用到Volatile关键字,因为Volatile的重要作用之一就是防止指令重排序。

    CPU还会存在合并写的现象。当第一条指令往上级缓存写入数据时,由于上级缓存访问速度比较慢,可能第二条指令又对上一条指令的结果进行了修改,那么CPU将这两条指令合并的最终结果一次性的写入到缓存中,这就成为合并写。

    3. 如何保证不乱序执行

    (1) 内存屏障:java采用的是内存屏障,内存屏障其实就是一个CPU指令,在硬件层面上来说可以扥为两种:Load Barrier 和 Store Barrier即读屏障和写屏障。主要有两个作用:

        a. 阻止屏障两侧的指令重排序;

        b. 强制把写缓冲区/高速缓存中的脏数据等写回主内存,让缓存中相应的数据失效。

    在JVM层面上来说作用与上面的一样有一个JSR内存屏障,种类可以分为四种:

    

    java底层实现Volatile的禁止指令重排序,也就是JVM会遵循自身的原则,对不同情况的指令添加不同类型的JSR内存屏障。

    上述只是再JVM中的实现,那么在系统底层是如何实现的呢?现在大多数的CPU都在底层有指令支持内存屏障的(不同的CUP的内存屏障指令会不一样,并且逻辑上也可能有区别),一共有3条CPU原语( 所谓原语,一般是指由若干条指令组成的程序段,用来实现某个特定功能,在执行过程中不可被中断),如下图:

    

    那么那些没有CPU原语来支持内存屏障的CPU又怎么实现呢,那就需要对总线进行加锁来实现。所以JVM中的内存屏障在不同的CUP中的实现方式是不一样的,一般是CPU原语支持,特殊情况下就是锁总线。

    (2) volatile的实现细节

        a. 字节码层面:编译成class文件后,变量的前面就有了一个修饰符valatile,是写在了二进制文件中的,如下图(结合class文件结构来看):

    

        b. jvm层面:对于所有volatile修饰的这块内存的写操作前加了一个StoreStoreBarrier,后面加了一个StoreLoadBarrier;这块内存的读操作前加了一个LoadLoadBarrier,后面加了一个LoadStoreBarrier。内存屏障两边的指令禁止重排序,来保证这块内容的读写不受CUP重排序的影响。如下图:

    

        c. os和硬件层面:使用hsdis观察汇编码,可以看到使用了lock指令,对内存区域加锁,如下图:

    (3) synchronized实现细节

        a. 字节码层面:如果是方法,就加一个ACC_SYNHRONIZED修饰符;同步代码块则是monitorenter和monitorexit两个指令。如下图:

    

        这里为什么会有两个monitorexit是因为正常执行完成需要一个,捕获异常而退出也需要一个。

        b. jvm层面:本地代码C和C++调用了操作系统提供的同步机制。

        c. os和硬件层面:x86系统采用lock comxchg xxxx,如下图:

三、总结

    本文详细介绍了JMM的整个知识体系结构,并且针对volatilesynchronized都做了不同层面的解析,希望各位能够有所收获。

    更多精彩内容,敬请扫描下方二维码,关注我的微信公众号【Java觉浅】,获取第一时间更新哦!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java觉浅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值