JVM基礎知識(二)Java記憶體模型

2021-09-11 16:24:01 字數 2065 閱讀 2874

volatile不需要加鎖, 比synchronized更輕量級, 不會阻塞執行緒; 從記憶體可見性角度看, volatile讀相當於加鎖, volatile寫相當於解鎖。

synchronized既能保證可見性, 又能保證原子性; volatile只能保證可見性,無法保證原子性。

退出同步塊 -> 釋放監視器 -> 重新整理緩衝區到主記憶體; 進入同步塊 -> 獲取監視器 -> 本地處理器快取失效 -> 重新從主記憶體載入變數。

執行緒a與執行緒b之間如要通訊: 首先,執行緒a把本地記憶體a中更新過的共享變數重新整理到主記憶體中去。然後,執行緒b到主記憶體中去讀取執行緒a之前已更新過的共享變數。

重排序分為三種: 編譯器優化的重排序, 指令級並行的重排序, 記憶體系統的重排序。

屏障型別

指令示例

說明loadload barriers

load1; loadload; load2

確保load1資料的裝載,之前於load2及所有後續裝載指令的裝載。

storestore barriers

store1; storestore; store2

確保store1資料對其他處理器可見(重新整理到記憶體),之前於store2及所有後續儲存指令的儲存。

loadstore barriers

load1; loadstore; store2

確保load1資料裝載,之前於store2及所有後續的儲存指令重新整理到記憶體。

storeload barriers

store1; storeload; load2

確保store1資料對其他處理器變得可見(指重新整理到記憶體),之前於load2及所有後續裝載指令的裝載。storeload barriers會使該屏障之前的所有記憶體訪問指令(儲存和裝載指令)完成之後,才執行該屏障之後的記憶體訪問指令。

資料依賴關係(分為三種: 寫後讀, 寫後寫, 讀後寫)

不管怎麼重排序(編譯器和處理器為了提高並行度),(單執行緒)程式的執行結果不能被改變。編譯器,runtime 和處理器都必須遵守as-if-serial語義。

順訊一致性記憶體模型是乙個被計算機科學家理想化了的理論參考模型。其有兩大特性:

同步程式的順序一致性效果:

jmm不保證未同步程式的執行結果與該程式在順序一致性模型中的執行結果一致。未同步程式在jmm和順序一致性模型的執行特性有以下差異:

volatile變數特性:

volatile寫-讀的記憶體語義:

小結: 執行緒a寫乙個volatile變數,隨後執行緒b讀這個volatile變數,這個過程實質上是執行緒a通過主記憶體向執行緒b傳送訊息。

為了實現volatile記憶體語義,jmm會分別限制編譯器重排序和處理器重排序, jmm針對編譯器制定的volatile重排序規則如下:

對於x86處理器,僅會對寫-讀操作做重排序。x86不會對讀-讀,讀-寫和寫-寫操作做重排序,因此在x86處理器中會省略掉這三種操作型別對應的記憶體屏障。在x86中,jmm僅需在volatile寫後面插入乙個storeload屏障即可正確實現volatile寫-讀的記憶體語義 。

鎖釋放與volatile寫有相同的記憶體語義;鎖獲取與volatile讀有相同的記憶體語義。

公平鎖記憶體語義的實現:

公平鎖和非公平鎖的區別:

基礎資料型別

寫final域的重排序規則:

引用型別

在建構函式內對乙個final引用的物件的成員域的寫入,與隨後在建構函式外把這個被構造的物件的引用賦值給乙個引用變數,這兩個操作之間不能重排序。

在建構函式返回前,被構造物件的引用不能為其他執行緒可見,因為此時的final域可能還沒有被初始化。在建構函式返回後,任意執行緒都將保證能看到final域正確初始化之後的值。

由於x86處理器不會對寫-寫操作和存在間接依賴關係的操作做重排序, 在x86處理器中,final域的讀/寫不會插入任何記憶體屏障!

jmm是乙個語言級的記憶體模型,處理器記憶體模型是硬體級的記憶體模型,順序一致性記憶體模型是乙個理論參考模型。處理器記憶體模型和語言記憶體模型都比順序一致性記憶體模型要弱。

jmm的設計:

jmm的記憶體可見性保證:

jsr-133對舊記憶體模型的修補:

Java基礎知識(二)

1.陣列的定義 一維陣列的定義int arrs 二維陣列的定義int darrs 陣列的初始化 靜態初始化 darrs new int,動態初始化 darrs new int 2 3 darrs 0 new int 5 給第乙個元素初始化2.方法 方法的呼叫 1 使用方法所屬的類建立乙個物件 a a...

java基礎知識 棧記憶體和堆記憶體

1.person p new person 定義乙個物件,且使用new關鍵字在堆記憶體中開闢空間。宣告 person p null 在棧記憶體中宣告,只開闢了棧記憶體空間,物件無法使用。例項化物件 new person 在堆記憶體總開闢空間,方可使用。總結就是 1.物件是儲存在棧記憶體中,屬性儲存在...

記憶體基礎知識

記憶體基礎知識 下面的列表總結了重要的 clr 記憶體概念。預設情況下,32 位計算機上的每個程序都具有 2 gb 的使用者模式虛擬位址空間。虛擬記憶體有三種狀態 如果用完保留的虛擬位址空間或提交的物理空間,則可能會用盡記憶體。記憶體不足的徵兆包括效能差 記憶體不足的通知以及顯示問題。例如,如果當計...