JAVA虚拟机-JMM内存模型(六)

1.JMM (Java Memory Model)内存模型相关概念

模型图:

可以对应下面这张图:

这张图告诉我们在线程运行的时候有一个内存专用的一小块内存,当Java程序会将变量同步到线程所在的内存,这时候会操作工作内存中的变量,而线程 中变量的值何时同步回主内存是不可预期的。但同时Java内存模型又告诉我们通过使用关键词“synchronized”或“volatile”可以让 Java保证某些约束:

“volatile” — 保证读写的都是主内存的变量
“synchronized” — 保证在块开始时都同步主内存的值到工作内存,而块结束时将变量同步回主内存.

 本地内存是什么,数据存在哪里?
     1、java内存模型的抽象概念
     2、并不在堆中,而是在cpu中的物理cache

可参考:http://www.cnblogs.com/dolphin0520/p/3920373.html 第一部分

Intel 的MESI协议,MESI协议保证了每个缓存中使用的共享变量的副本是一致的。它核心的思想是:当CPU写数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。

 

 跨核访问需要通过Memory Controller
问题:为什么需要这样?
     访问快!!
     就像:访问mysql时,常用结果会被缓存到redis等缓存产品一样;
     Cpu与内存的交互速度远慢于cpu的运算速度为了提高处理速度,先进系统内存的数据读到内存缓存(L1,L2,L3等)
缓存行(Cache line)
 为了高效地存取缓存, 不是简单随意地将单条数据写入缓存的.  缓存是由缓存行组成的, 典型的一行是64字节.

读者可以通过下面的shell命令,查看cherency_line_size就知道知道机器的缓存行是多大。
  cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size  

 查看下面这台机器: 16个cpu 每个为4核  缓存行64字节

 2.并发编程几个重要概念

2.1 三个特性

在并发编程中,我们通常会遇到以下三个问题:原子性问题,可见性问题,有序性问题。我们先看具体看一下这三个概念:

1).原子性

     原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。

2).可见性

  可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

3).有序性

  有序性:即程序执行的顺序按照代码的先后顺序执行。

2.2 重排序

JMM属于语言级的内存模型,它确保在 不同的编译器不同的处理器平台之上, 通过禁止特定类型的编译器重排序和处理器重排序,为程序员提供一致的内存可见性保证
对于编译器冲排序,JMM的编译器重排序规则会禁止特定类型的编译器重排序(不是所有的编译器重排序都要禁止)。
对于处理器重排序,JMM的处理器重排序规则会要求java编译器在生成指令序列时,插入特定类型的 内存屏障(memory barriers,intel称之为memory fence)指令,通过内存屏障指令来禁止特定类型的处理器重排序(不是所有的处理器重排序都要禁止)。

引申:

在执行程序时为了提高性能,编译器和处理器常常会对指令做重排序。重排序分三种类型:

  1. 编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。
  2. 指令级并行的重排序。现代处理器采用了指令级并行技术(Instruction-Level Parallelism, ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。
  3. 内存系统的重排序。由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行。

上述的1属于编译器重排序,2和3属于处理器重排序。这些重排序都可能会导致多线程程序出现 内存可见性问题  2.3 内存屏障memory Barriers 内存屏障类型
   
volatile语义中内存屏障的插入策略
     在每个volatile写前面插入SS
     在每个volatile写后面插入SL
     在每个volatile读后面插入LL,插入LS
连续的操作之间多余的内存屏障会由编译器觉得是否省略。
     同时,不同的操作系统所允许的重排序类型也不尽相同,例如x86只允许sl重排序,所以其实只需要加这一种内存屏障即可。
 

1.解决以下问题:

1).JMM内存模型中本地缓存和工作内存是什么关系?

2).重排序在什么时候进行?(JIT编译优化时进行)

3).什么是内存屏障Memory Barriers,内存屏障帮我做了什么?4).内存屏障的4种插入形式?

5).原子性 可见性 重排序 顺序一致性的解释?

6).volatile,synchronized,final的语义

7).as-id-serial,happens-before的语义

相关文章:

参考:

1.聊聊我对Java内存模型的理解

       2.Java并发编程:volatile关键字解析

      3.并发编程网: JAVA内存模型

猜你喜欢

转载自yanan0628.iteye.com/blog/2286557