JVM内存模型系列(一)并发的舞台:内存模型-创新互联
摩尔定律,通俗的说就是:每18到24个月,集成电路上可容纳的元器件数目便会增加一倍,芯片的性能也会随之翻一番。
成都创新互联是一家集网站建设,中宁企业网站建设,中宁品牌网站建设,网站定制,中宁网站建设报价,网络营销,网络优化,中宁网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。而Amdahl定律是一个计算机科学界的经验法则,因吉恩·阿姆达尔而得名。它代表了处理器并行运算之后效率提升的能力。
当摩尔定律被认为即将失效,硬件性能快要到达极限时,Amdahl定律发挥了作用,并发处理的广泛应用,能大效率地榨干我们所用机器的运算资源。
多任务(并发)的起源经常在新闻上看到,什么超级计算机又每秒多少亿运算,但是我们看视频,刷剧可能还是不时会卡。
因为我们现在使用的设备,cpu的运算速度比存储以及网络通信子系统相差非常大。
为了在看视频卡顿的时候,你还能看看PDF,用个计算器算账,多任务就出现了。
另外,在服务端编程这块,多任务是必须的,因为你的软件要同时为很多用户服务,比如说双十一的秒杀,每个顾客的请求,都是计算机要去完成的一个任务。
充分利用计算机的处理能力说白了,就是程序员要充分利用计算机的处理能力,让业务组件的TPS(transaction per second)足够高。
并发的挑战和福音写好并发程序是困难的,好在 Java语言和虚拟机提供了非常多并发的工具,降低了并发编程的门槛,让上层编码人员关注业务本身。
当我们在上层熟练业务之余,不妨来了解一下支持我们在业务中,进行并发编程的基石。
硬件的效率和一致性为了提升效率,我们找房子就先去找中介,而不是一个个房子敲门去问。
同样,cpu为了更高效于存储,通信子系统沟通,就出现了高速缓存。
我们知道,操作系统是管理硬件资源的,那么管理包含 高速缓存 的这种操作系统,就是共享内存多核系统。
这种操作系统下的真实机器 的内存模型(memory model),就会是这个样子:
处理器->高速缓存->缓存一致性协议->主内存
还是上面中介的例子,你可以把 高速缓存, 缓存一致性协议理解为:中介小哥,和中介小哥们在的公司。
缓存一致性协议保证了cpu在访问高速缓存时的正确性,它包含几种典型的协议:
• MSI
• MESI 这是一种常用的缓存一致性协议
• MOSI
• Synapse
• Dragon Protocol
内存模型就是:特定的操作协议下,对内存和高速缓存的读写访问的过程抽象。
类比找房子,你是去链家还是贝壳或者安居客呢?他们有差不多的业务流程和服务风格,尽管有些微差异,但都能帮你找到房子。
屏蔽一些恼人的细节如果你听说过 cpu的乱序执行,jvm的即时编译器也有指令重排序 这两件事情,那么你会好奇:指令不是我在代码里写的那种执行顺序,程序还能正确出结果?
是的,可以!
内存模型就有这一方面的功效,我们先看看 JMM 的历史。
JMM初识太古早的历史我们不去深究,你需要知道的是,从JDK 5 实现了 JSR-133 这个提案的要求后,Java 内存模型才叫一个成熟。
这是Java面世九年后,在2004年才搞定的,为啥这么慢?因为这个模型
1) 必须严谨
内存访问不会有任何歧义, 不然bug满天飞可就毁了Java这门语言以及后面庞大的生态。
2) 又要宽松
Java本身是要跨平台的,而JVM就是它跨平台的地基。
JVM自己本身非常希望充分利用物理机器的各种优良特性,来取得在这台机器上的更好性能,所以它不得不在多种机器上进行适配调整。
如此Java语言就能在各种机器上有相同的行为表现,不至于出现在C/C++生态里面的,“在我这种机器上可以跑啊,怎么到你哪就各种编译不过,跑着跑着就segment fault 了” 的问题。
主内存 和 工作内存如果你记得我上面提过的物理机器增加高速缓存后的内存模型,那么这里我们来做一个对比:JMM(Java Memory Model)类比物理机器的内存模型。
物理机器增加高速缓存后的内存模型:
处理器->高速缓存->缓存一致性协议->主内存
JMM:
Java线程->工作内存->Save和Load操作->主内存
请记住,内存是变量的大池子。
当我们 回到 内存模型,就会明白内存模型的实质目的:内存模型就是 定义你写的各种变量的访问规则。
包括:
• 实例中的各种字段,属性变量
• 静态字段
• 数组里面的元素
但是不包括:
• 局部变量(方法里面单独声明的,而非类的成员)
• 方法参数(方法括号里面的,这是方法调用是,放入各个线程自己的执行栈的)
因为这些是线程私有的,不存在读写竞争。
在理清所有的访问规则前,我们需要知道,变量的访问(读写)在哪里发生?
对于JMM,这一切在主内存和工作内存发生。
主内存你知道,JVM虚拟机跑起来时,本身会在物理机上占用一块内存,然后它会再划分出一块内存,当作JMM的主内存。
工作内存虚拟机里面有许多活动的线程,而每个线程拥有自己的工作内存,里面存储了被该线程使用的变量的主内存副本。
线程实际上操作的变量,全是在工作内存里,而不是主内存。
不同线程之间,不会打扰对方的工作内存,不会互相访问。
线程他们总是通过主内存进行变量的同步。
volatile 变量看起来直接驻留在主内存(因为每次读写总是取得最新结果),但实际上也会在线程的工作内存有副本。(特殊的操作顺序性保证了它总是崭新的状态)
和我们通常理解的Java内存区域的异同如果你了解过Java虚拟机的内存划分,那么你知道它的运行时数据区,分为堆内存,虚拟机栈,本地方法栈,PC程序计数器,方法区。
这和JMM有关系吗?
其实没有任何关系[手动狗头]
但是你硬要联系起来记忆的话,你可以这样理解:
主内存,对应Java堆中的实例的数据部分,存储在物理机的主内存中。
但是不对应堆里面保存的其他数据,说的就是不包括:
* MarkWord
* 对象hash码
* GC标志
* GC年龄
* 同步锁信息
* KlassPoint
* Padding
而 工作内存 对应 虚拟机栈的部分区域,反映在物理实体上,就是存储在物理机的寄存器和高速缓存中。
再看看这个图,是不是清晰了很多:
下篇预告在本篇中,我们分享了一些Java内存模型的起源,定义,概览。下一篇就是具体的规则,正是这些规则,保证了我们并发编程的正确性。
如果您感兴趣,欢迎分享给其他小伙伴,谢谢!
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站名称:JVM内存模型系列(一)并发的舞台:内存模型-创新互联
本文网址:http://scjbc.cn/article/dcgsii.html