Java多線程12-內存模型

1、 高速緩存
由於主內存執行一次內存讀、寫操做所需時間可能足夠處理器執行上百條的指令,爲了彌補差距、引入了高速緩存Cache緩存

高速緩存:是一種存取速率遠比內存大而容量遠比內存小的存儲部件,每一個處理器都有其高速緩存
高速緩存至關於爲程序所訪問的每一個變量保留了一份相應內存空間所存儲數據(變量值)的副本,因爲高速緩存的存儲容量遠小於主內存,因此高速緩存並非每時每刻保留着全部變量值的副本。
高速緩存結構:至關於硬件實現的容量極小的散列表(Hash Table),其鍵(Key)是一個內存地址,其值(Value)是內存數據的副本或者準備寫入內存的數據;其內部結構至關於一個拉鍊散列表(Chained Hash Table),它包含若干桶(Bucket)每一個桶又分爲若干條目(Cache Entry)性能優化


緩存條目:內部劃分爲Tag,Data Block,Flag這三部分,Data Block又稱緩存行(Cache Line)是高速緩存與主內存之間的數據交換最小單元,用於從內存中讀取的或者準備寫往內存的數據;Tag則包含了緩存行中數據相應的內存地址的部分信息(內存地址的高位部分比特),Flag用於表示相應緩存行的狀態信息;


現代處理器通常具備多個層次的高速緩存,如圖所示、一級緩存可能直接被集成在處理器的內核(Core)裏,所以訪問效率很是高,距離處理器越近的高速緩存,其存取速率越快,成本越高、容量越小。

2、 緩存一致性協議
數據世界的交通規則
多線程併發訪問同一個共享變量的時候,這些線程的執行處理器上的高速緩存各自都會保留一份該共享變量的副本,隨之帶來一個新問題:一個處理器對其副本數據進行更新以後,其餘處理器如何察覺該更新並作出適當反應,以確保這些處理器後續讀取該共享變量時可以讀取到這個更新;這就是緩存一致性問題,爲解決這問題、創建了通訊機制—緩存一致性協議
MESI(Modified-Exculsive-Shared-Invalid)協議爲一種廣爲使用的緩存一致性協議,它使得針對同一地址的讀內存操做是併發的,而針對同一地址的寫內存操做是獨佔的
3、 寫緩衝器與無效化隊列
MESI協議解決了緩存一致性問題,但新的問題也產生了:處理器執行寫內存操做時,必須等待其餘全部處理器將其高速緩存中的相應副本數據刪除並接收到這些處理器所回覆的Invalidate Acknowledge/Read Response消息以後才能將數據寫入高速緩存;爲規避和減小這種等待形成的寫操做延遲,引入了寫緩衝器和無效化隊列
寫緩衝器(Store Buffer)是處理器內部的一個容量比高速緩存還小的私有高速存儲部件,每一個處理器都有其寫緩衝器,寫緩衝器內部可包含若干條目(Entry)一個處理器沒法讀取另外一處理器上的寫緩衝器內容微信


寫緩衝器的引入:使得處理器在執行寫操做的時候能夠不等待Invalidate Acknowledge消息,從而減小了寫操做延時,使得寫操做的處理器在其餘處理器回覆Invalidate Acknowledge/Read Response消息這段時間內可以執行其餘指令,從而提升處理器指令執行效率
無效化隊列的引入:處理器在接收到Invalidate消息以後並不刪除消息中指定地址對應的副本數據,而是將消息存入無效化隊列以後就回復Invalidate Acknowledge消息,從而減小寫操做執行處理器所需等待時間
寫緩衝器和無效化隊列的引入又會帶來新的問題:內存重排序、可見性問題
存儲轉發:處理器直接從寫緩衝器中讀取數據來實現內存讀操做
內存屏障(Store Barrier):解決內存重排序問題的特殊指令
加載屏障(Load Barrier):解決可見性問題

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虛擬機會作一些優化:省略、合併等併發

更多內容,請關注微信公衆號:
性能

相關文章
相關標籤/搜索