深入理解Java内存模型(七)——总结

处理器内存模型

顺序一致性内存模型是一个理论参考模型,JMM和处理器内存模型在设计时通常会把顺序一致性内存模型作为参照。JMM和处理器内存模型在设计时会对顺序一致性模型做一些放松,因为如果完全按照顺序一致性模型来实现处理器和JMM,那么很多的处理器和编译器优化都要被禁止,这对执行性能将会有很大的影响。

根据对不同类型读/写操作组合的执行顺序的放松,可以把常见处理器的内存模型划分为下面几种类型:

  1. 放松程序中写-读操作的顺序,由此产生了total store ordering内存模型(简称为TSO)。
  2. 在前面1的基础上,继续放松程序中写-写操作的顺序,由此产生了partial store order 内存模型(简称为PSO)。
  3. 在前面1和2的基础上,继续放松程序中读-写和读-读操作的顺序,由此产生了relaxed memory order内存模型(简称为RMO)和PowerPC内存模型。

注意,这里处理器对读/写操作的放松,是以两个操作之间不存在数据依赖性为前提的(因为处理器要遵守as-if-serial语义,处理器不会对存在数据依赖性的两个内存操作做重排序)。

下面的表格展示了常见处理器内存模型的细节特征:

内存模型名称

对应的处理器

Store-Load 重排序

Store-Store重排序

Load-Load 和Load-Store重排序

可以更早读取到其它处理器的写

可以更早读取到当前处理器的写

TSO

sparc-TSO

X64

Y

   

Y

PSO

sparc-PSO

Y

Y

  

Y

RMO

ia64

Y

Y

Y

 

Y

PowerPC

PowerPC

Y

Y

Y

Y

Y

在这个表格中,我们可以看到所有处理器内存模型都允许写-读重排序,原因在第一章以说明过:

它们都使用了写缓存区,写缓存区可能导致写-读操作重排序。同时,我们可以看到这些处理器内

存模型都允许更早读到当前处理器的写,原因同样是因为写缓存区:由于写缓存区仅对当前处理器

可见,这个特性导致当前处理器可以比其他处理器先看到临时保存在自己的写缓存区中的写。

上面表格中的各种处理器内存模型,从上到下,模型由强变弱。越是追求性能的处理器,内存模型设计的会越弱。因为这些处理器希望内存模型对它们的束缚越少越好,这样它们就可以做尽可能多的优化来提高性能。

由于常见的处理器内存模型比JMM要弱,java编译器在生成字节码时,会在执行指令序列的适当位置插入内存屏障来限制处理器的重排序。同时,由于各种处理器内存模型的强弱并不相同,为了在不同的处理器平台向程序员展示一个一致的内存模型,JMM在不同的处理器中需要插入的内存屏障的数量和种类也不相同。下图展示了JMM在不同处理器内存模型中需要插入的内存屏障的示意图:

如上图所示,JMM屏蔽了不同处理器内存模型的差异,它在不同的处理器平台之上为java程序员呈现了一个一致的内存模型。

JMM,处理器内存模型与顺序一致性内存模型之间的关系

JMM是一个语言级的内存模型,处理器内存模型是硬件级的内存模型,顺序一致性内存模型是一个理论参考模型。下面是语言内存模型,处理器内存模型和顺序一致性内存模型的强弱对比示意图:

从上图我们可以看出:常见的4种处理器内存模型比常用的3中语言内存模型要弱,处理器内存模型和语言内存模型都比顺序一致性内存模型要弱。同处理器内存模型一样,越是追求执行性能的语言,内存模型设计的会越弱。

JMM的设计

从JMM设计者的角度来说,在设计JMM时,需要考虑两个关键因素:

  • 程序员对内存模型的使用。程序员希望内存模型易于理解,易于编程。程序员希望基于一个强内存模型来编写代码。
  • 编译器和处理器对内存模型的实现。编译器和处理器希望内存模型对它们的束缚越少越好,这样它们就可以做尽可能多的优化来提高性能。编译器和处理器希望实现一个弱内存模型。

由于这两个因素互相矛盾,所以JSR-133专家组在设计JMM时的核心目标就是找到一个好的平衡点:一方面要为程序员提供足够强的内存可见性保证;另一方面,对编译器和处理器的限制要尽可能的放松。下面让我们看看JSR-133是如何实现这一目标的。

为了具体说明,请看前面提到过的计算圆面积的示例代码:

double pi  = 3.14;    //A
double r   = 1.0;     //B
double area = pi * r * r; //C

上面计算圆的面积的示例代码存在三个happens- before关系:

  1. A happens- before B;
  2. B happens- before C;
  3. A happens- before C;

由于A happens- before B,happens- before的定义会要求:A操作执行的结果要对B可见,且A操作的执行顺序排在B操作之前。 但是从程序语义的角度来说,对A和B做重排序即不会改变程序的执行结果,也还能提高程序的执行性能(允许这种重排序减少了对编译器和处理器优化的束缚)。也就是说,上面这3个happens- before关系中,虽然2和3是必需要的,但1是不必要的。因此,JMM把happens- before要求禁止的重排序分为了下面两类:

  • 会改变程序执行结果的重排序。
  • 不会改变程序执行结果的重排序。

JMM对这两种不同性质的重排序,采取了不同的策略:

  • 对于会改变程序执行结果的重排序,JMM要求编译器和处理器必须禁止这种重排序。
  • 对于不会改变程序执行结果的重排序,JMM对编译器和处理器不作要求(JMM允许这种重排序)。

下面是JMM的设计示意图:

从上图可以看出两点:

  • JMM向程序员提供的happens- before规则能满足程序员的需求。JMM的happens- before规则不但简单易懂,而且也向程序员提供了足够强的内存可见性保证(有些内存可见性保证其实并不一定真实存在,比如上面的A happens- before B)。
  • JMM对编译器和处理器的束缚已经尽可能的少。从上面的分析我们可以看出,JMM其实是在遵循一个基本原则:只要不改变程序的执行结果(指的是单线程程序和正确同步的多线程程序),编译器和处理器怎么优化都行。比如,如果编译器经过细致的分析后,认定一个锁只会被单个线程访问,那么这个锁可以被消除。再比如,如果编译器经过细致的分析后,认定一个volatile变量仅仅只会被单个线程访问,那么编译器可以把这个volatile变量当作一个普通变量来对待。这些优化既不会改变程序的执行结果,又能提高程序的执行效率。

JMM的内存可见性保证

Java程序的内存可见性保证按程序类型可以分为下列三类:

  1. 单线程程序。单线程程序不会出现内存可见性问题。编译器,runtime和处理器会共同确保单线程程序的执行结果与该程序在顺序一致性模型中的执行结果相同。
  2. 正确同步的多线程程序。正确同步的多线程程序的执行将具有顺序一致性(程序的执行结果与该程序在顺序一致性内存模型中的执行结果相同)。这是JMM关注的重点,JMM通过限制编译器和处理器的重排序来为程序员提供内存可见性保证。
  3. 未同步/未正确同步的多线程程序。JMM为它们提供了最小安全性保障:线程执行时读取到的值,要么是之前某个线程写入的值,要么是默认值(0,null,false)。

下图展示了这三类程序在JMM中与在顺序一致性内存模型中的执行结果的异同:

只要多线程程序是正确同步的,JMM保证该程序在任意的处理器平台上的执行结果,与该程序在顺序一致性内存模型中的执行结果一致。

JSR-133对旧内存模型的修补

JSR-133对JDK5之前的旧内存模型的修补主要有两个:

  • 增强volatile的内存语义。旧内存模型允许volatile变量与普通变量重排序。JSR-133严格限制volatile变量与普通变量的重排序,使volatile的写-读和锁的释放-获取具有相同的内存语义。
  • 增强final的内存语义。在旧内存模型中,多次读取同一个final变量的值可能会不相同。为此,JSR-133为final增加了两个重排序规则。现在,final具有了初始化安全性。

参考文献

  1. Computer Architecture: A Quantitative Approach, 4th Edition
  2. Shared memory consistency models: A tutorial
  3. Intel® Itanium® Architecture Software Developer’s Manual Volume 2: System Architecture
  4. Concurrent Programming on Windows
  5. JSR 133 (Java Memory Model) FAQ
  6. The JSR-133 Cookbook for Compiler Writers
  7. Java theory and practice: Fixing the Java Memory Model, Part 2

 

 

 

 

来源:http://www.infoq.com/cn/articles/java-memory-model-7?utm_source=infoq&utm_medium=related_content_link&utm_campaign=relatedContent_articles_clk

转载于:https://www.cnblogs.com/94julia/archive/2013/05/30/3107686.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/274225.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

沉浸式ui设计_有助于沉浸的视频游戏UI —武器轮

沉浸式ui设计Many action-adventure games rely on the feeling of thrills via bullets, fire, grenade, more bullets, and gigantic booms. The way to enable all these is to offer a massive arsenal, from machetes to assault rifles all the way till bazookas.许多动…

ux设计师薪水_客户现在也是UX设计师

ux设计师薪水Some of you probably know by now, I’m not too fond of the monster the UX industry has become. It’s overblown, overcomplicated and often dishonest towards the clients. It’s also in itself undefined. (where is the E in Experience?)你们中的某些…

分步表单_角色创建分步指南

分步表单The first thing most of us designers are taught is the concept of personas and the necessity of them when it comes to UX and product design. However, knowing is different from applying and it can be difficult to know where to begin when we’re aske…

svg配合css3动画_带有Adobe Illustrator,HTML和CSS的任何网站的SVG动画

svg配合css3动画A top trend in web design for 2020 is the increased use of SVG animations on web pages and in logo design. In this article, we will implement a simple and straight forward method to create relatively complex animation. We will use Adobe Illu…

基于pt100温度计仿真_基于8pt网格的设计系统

基于pt100温度计仿真重点 (Top highlight)This article is the 2nd in a two part series — to the previous chapter in which I demonstrate how to establish an 8pt grid.本文是该系列文章的第二部分 ,这是上一章 的第二部分 ,在上一章中&#xff0…

利用 k8s 建立软件商店_为企业建立应用商店

利用 k8s 建立软件商店It’s June 2019. I’m sitting in a conference room in Research Triangle Park in North Carolina. At the end of the table are the two executives that have been tapped to lead a new endeavor on behalf of IBM’s $34 billion acquisition of …

苹果复兴_类型复兴的故事:来自Type West的经验教训

苹果复兴Last Fall, I began the 去年秋天,我开始 在旧金山的Type West program at the Letterform档案库中Letterform Archive in San Francisco. For those of you who don’t know, the Letterform Archive is creative heaven — a type nerd’s letter art co…

C#调用ATL COM

作者:朱金灿 来源:http://blog.csdn.net/clever101 简单介绍C#程序如何调用ATL编写的COM组件。 首先新建一个ATL工程,具体如下: 1. 填写工程名称和路径,如下图: 2. 选择工程的服务器类型为动态链接库&a…

浪潮世科和浪潮软件什么关系_社交图形浪潮

浪潮世科和浪潮软件什么关系Nowadays, the cornucopia of graphics seems like a given. However, it was not so long ago that infographics were scarce and lived in closed ecosystems. The majority of graphics were published in newspapers, magazines, or books, and…

PHP图形图像的典型应用 --常用图像的应用(验证码)

php生成动态的验证码&#xff0c;是php防止恶意登陆或者注册等常规手段-废话不多说&#xff0c;直接看例子。&#xff08;只是一个简单的应用&#xff0c;如果要安全或者更复杂的&#xff0c;请期待我以后的文章&#xff09; PHP生成验证码核心文件 (checks.php): <?php/*成…

写saas创业的书_我在SaaS创业公司担任UX设计师的第一个月中学到的三件事

写saas创业的书I recently transitioned from being a copywriter at an ad agency to a UX Designer at a SaaS startup. To add more multidisciplinary skills into the mix, I graduated with a Bachelor in Accountancy.我最近从一名广告代理商的撰稿人过渡到了SaaS初创公…

ui项目答辩中学到了什么_我在UI设计9年中学到的12件事

ui项目答辩中学到了什么重点 (Top highlight)I know these can seem a bit clich but I will try to explain everything from my own experience.我知道这些内容似乎有些陈词滥调&#xff0c;但我会尝试根据自己的经验来解释所有内容。 第一名 (No.1 Never assume) The first…

ux的重要性_UX中清晰的重要性

ux的重要性重点 (Top highlight)Times, since the very first occurrences of web design in the 90’s, have changed a lot design-wise. The particular technology and its applications got more stable. Human-computer interaction (HCI) was deeply researched, design…

可靠消息最终一致性设计_如何最终启动您的设计产品组合

可靠消息最终一致性设计It’s not a secret that most designers procrastinate on their portfolios whether it is to update them or to create them in the first place.大多数设计师在更新产品组合时还是拖延产品组合并不是秘密。 首先创建它们 。 Hopefully, by the e…

游戏用户体验指标_电子游戏如何超越游戏化的用户体验

游戏用户体验指标游戏UX (GAMES UX) During a time when the time spent on video games has reached record breaking heights, due to excessive time indoors, gamification has more of a place now than ever before.d uring的时候花在视频游戏的时间已经达到了 破纪录的高…

JAVA编程心得-JAVA实现CRC-CCITT(XMODEM)算法

CRC即循环冗余校验码&#xff08;Cyclic Redundancy Check&#xff09;&#xff1a;是数据通信领域中最常用的一种差错校验码&#xff0c;其特征是信息字段和校验字段的长度可以任意选定。 1 byte checksum CRC-16 CRC-16 (Modbus) CRC-16 (Sick) …

什么字体字母和数字大小一样_字母和字体如何适应我们的屏幕

什么字体字母和数字大小一样Writing went through many iterations before it became what is today. Times New Roman wasn’t the default script for ancient Egyptians, in fact, paper didn’t even exist when the first words were written.写作经历了许多迭代&#xff…

jenkins 通过批处理自动构建 非标准项目

之前介绍了java和vs2010的项目构建&#xff0c;这些都是比较常见的&#xff0c;所以都用专门的工具。但但难免会遇到一些不常见的项目&#xff0c;下面介绍通过批处理进行构建&#xff0c;并用jenkins调用.我们这里使用plc语言&#xff0c;没有标准环境&#xff0c;只有使用bat…

效果图底图 线框图_5分钟的线框图教程

效果图底图 线框图为什么使用线框&#xff1f; (Why wireframe?) Simply put, wireframes provide a structure and layout for content and assets.简而言之&#xff0c;线框提供了内容和资产的结构和布局。 You can wireframe just about any kind of presentation, from p…

多线程 - 你知道线程栈吗

问题 1. local 变量的压栈和出栈过程 void func1(){ int a 0; int b 0; } 系统中有一个栈顶指针&#xff0c;每次分配和回收local 变量时&#xff0c;其实就是移动栈指针。 2. static local变量的分配风险 void func2(){ static int a 0; } 这个变量a可能会被分…