1、 高速缓存
由于主内存执行一次内存读、写操做所需时间可能足够处理器执行上百条的指令,为了弥补差距、引入了高速缓存Cache缓存
高速缓存:是一种存取速率远比内存大而容量远比内存小的存储部件,每一个处理器都有其高速缓存
高速缓存至关于为程序所访问的每一个变量保留了一份相应内存空间所存储数据(变量值)的副本,因为高速缓存的存储容量远小于主内存,因此高速缓存并非每时每刻保留着全部变量值的副本。
高速缓存结构:至关于硬件实现的容量极小的散列表(Hash Table),其键(Key)是一个内存地址,其值(Value)是内存数据的副本或者准备写入内存的数据;其内部结构至关于一个拉链散列表(Chained Hash Table),它包含若干桶(Bucket)每一个桶又分为若干条目(Cache Entry)性能优化
2、 缓存一致性协议
数据世界的交通规则
多线程并发访问同一个共享变量的时候,这些线程的执行处理器上的高速缓存各自都会保留一份该共享变量的副本,随之带来一个新问题:一个处理器对其副本数据进行更新以后,其余处理器如何察觉该更新并作出适当反应,以确保这些处理器后续读取该共享变量时可以读取到这个更新;这就是缓存一致性问题,为解决这问题、创建了通讯机制—缓存一致性协议
MESI(Modified-Exculsive-Shared-Invalid)协议为一种广为使用的缓存一致性协议,它使得针对同一地址的读内存操做是并发的,而针对同一地址的写内存操做是独占的
3、 写缓冲器与无效化队列
MESI协议解决了缓存一致性问题,但新的问题也产生了:处理器执行写内存操做时,必须等待其余全部处理器将其高速缓存中的相应副本数据删除并接收到这些处理器所回复的Invalidate Acknowledge/Read Response消息以后才能将数据写入高速缓存;为规避和减小这种等待形成的写操做延迟,引入了写缓冲器和无效化队列
写缓冲器(Store Buffer)是处理器内部的一个容量比高速缓存还小的私有高速存储部件,每一个处理器都有其写缓冲器,写缓冲器内部可包含若干条目(Entry)一个处理器没法读取另外一处理器上的写缓冲器内容微信
4、 基本内存屏障
LoadLoad屏障、LoadStore屏障、StoreStore屏障、StoreLoad屏障多线程
5、 Java同步机制与内存屏障
Java虚拟机对synchronized、volatile和final关键字的语义实现就是借助内存屏障
复合屏障:又基本内存屏障组合而成
获取屏障:LoadLoad屏障和LoadStore屏障的组合,可以禁止该屏障以前的任何读操做与该屏障以后的任何读、写操做之间进行重排序
释放屏障:LoadStore屏障和StoreStore屏障组合,可以禁止该屏障以前的任何读、写操做与该屏障以后的任何写操做之间进行重排序
volatile关键字的实现
Java虚拟机在volatile变量写操做以前插入的释放屏障使得该屏障以前的任何读、写操做都先于这个volatile变量写操做被提交,而Java虚拟机在volatile变量读操做以后插入的获取屏障使得这个volatile变量读操做先于该屏障以后的任何读、写操做被提交。
Synchronized关键字的实现
Java虚拟机会在monitorenter(用于申请锁的字节码指令)对应的指令后临界区开始前的地方插入一个获取屏障;Java虚拟机会在临界区结束后的monitorenter(用于释放锁的字节码指令)对应的指令前的地方插入一个释放屏障。获取屏障和释放屏障一块儿保证了临界区的操做具备原子性。
final关键字的实现
Java虚拟机在插入StoreStore屏障后保障编译器不将final字段的初始化操做重排序
内存屏障部分禁止重排序的代价就是它会阻止编译器、处理器作一些性能优化,另外一个涉及的冲刷写缓冲器和清空无效化队列的动做比价耗时,因此Java虚拟机会作一些优化:省略、合并等并发
更多内容,请关注微信公众号:
性能