一、 高速缓存
因为主内存执行一次内存读、写操作所需时间可能足够处理器执行上百条的指令,为了弥补差距、引入了高速缓存Cache高速缓存:是一种存取速率远比内存大而容量远比内存小的存储部件,每个处理器都有其高速缓存
高速缓存相当于为程序所访问的每个变量保留了一份相应内存空间所存储数据(变量值)的副本,由于高速缓存的存储容量远小于主内存,所以高速缓存并不是每时每刻保留着所有变量值的副本。高速缓存结构:相当于硬件实现的容量极小的散列表(Hash Table),其键(Key)是一个内存地址,其值(Value)是内存数据的副本或者准备写入内存的数据;其内部结构相当于一个拉链散列表(Chained Hash Table),它包含若干桶(Bucket)每个桶又分为若干条目(Cache Entry)二、 缓存一致性协议
数据世界的交通规则多线程并发访问同一个共享变量的时候,这些线程的执行处理器上的高速缓存各自都会保留一份该共享变量的副本,随之带来一个新问题:一个处理器对其副本数据进行更新之后,其他处理器如何察觉该更新并做出适当反应,以确保这些处理器后续读取该共享变量时能够读取到这个更新;这就是缓存一致性问题,为解决这问题、建立了通信机制—缓存一致性协议MESI(Modified-Exculsive-Shared-Invalid)协议为一种广为使用的缓存一致性协议,它使得针对同一地址的读内存操作是并发的,而针对同一地址的写内存操作是独占的三、 写缓冲器与无效化队列MESI协议解决了缓存一致性问题,但新的问题也产生了:处理器执行写内存操作时,必须等待其他所有处理器将其高速缓存中的相应副本数据删除并接收到这些处理器所回复的Invalidate Acknowledge/Read Response消息之后才能将数据写入高速缓存;为规避和减少这种等待造成的写操作延迟,引入了写缓冲器和无效化队列写缓冲器(Store Buffer)是处理器内部的一个容量比高速缓存还小的私有高速存储部件,每个处理器都有其写缓冲器,写缓冲器内部可包含若干条目(Entry)一个处理器无法读取另一处理器上的写缓冲器内容四、 基本内存屏障
LoadLoad屏障、LoadStore屏障、StoreStore屏障、StoreLoad屏障五、 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虚拟机会做一些优化:省略、合并等更多内容,请关注微信公众号: