這樣看java記憶體模型其實很簡單

JAVA一方發表於2020-01-10

java記憶體模型

簡稱JMM(Java Memory Model),個人對於JMM理解是:JVM遮蔽了作業系統對於實體記憶體訪問的複雜性,目的從軟體設計角度呈現出的一種記憶體訪問的邏輯檢視 。也就是JMM是JVM為軟體工程師提供的一系列記憶體訪問的邏輯規則,理解併合理使用這些規則就能正確訪問記憶體,至於底層和實體記憶體直接互動動作已經被透明化了,無須關心。下圖是JMM記憶體模型檢視,是記憶體訪問規則的基礎。

這樣看java記憶體模型其實很簡單

這樣看java記憶體模型其實很簡單 

主記憶體 : 主記憶體是 執行緒公有的 ,是所有執行緒都能訪問的記憶體區域, 一般對應於java記憶體佈局中的堆區。

工作記憶體 工作記憶體是 執行緒私有的 。一般對應於JVM虛擬機器棧,以及本地方法棧 

工作記憶體和主記憶體之分 

從邏輯上看,如果沒有主記憶體和工作記憶體的區分,只有一整塊的記憶體,似乎也並無不妥。 那麼區分主記憶體和工作記憶體的意義何在?

這樣看java記憶體模型其實很簡單

這樣看java記憶體模型其實很簡單 

上圖是耳熟能詳的馮諾依曼體系結構,現代計算機是基於馮諾依曼體系上發展起來的。該體系有兩個關鍵的組成就是 儲存器和CPU(運算器和控制器) 。 其中儲存器則是我們所討論的實體記憶體。 CPU和記憶體之間的IO操作是存在瓶頸的,記憶體的操作速度遠遠小於CPU的運算速度 。在CPU和記憶體協同工作的場景中,CPU以較短的時間完成數值計算後,需要花較長的時間等待記憶體讀取操作,造成了CPU運算資源的浪費。 於是,位於CPU和記憶體之間的快取記憶體應運而生。

這樣看java記憶體模型其實很簡單

在引入了快取記憶體之後,CPU會將運算所需要的資料一次性的載入到快取記憶體中,高速緩衝具備比記憶體更快的存取速度。CPU和快取記憶體之間配合大大提高了CPU資源的利用率。 此時在看工作記憶體和主記憶體關係,從邏輯上,快取記憶體對應工作記憶體,每個執行緒分配到CPU時間片時,獨自享有快取記憶體的使用能力。主記憶體對應儲存的實體記憶體。特別注意,這只是邏輯上的對等關係,物理的上具體對應關係十分複雜,這裡不討論。  

二丶工作記憶體和主記憶體之間的互動規則 

工作記憶體和主記憶體之間協同工作才是JMM的核心部分。從上文描述中可以知道,工作記憶體是主記憶體部分內容的拷貝,在多執行緒環境中,可能存在多份主記憶體的拷貝。 CPU是直接操作工作記憶體,最後將工作記憶體同步到主記憶體,這個過程會造成各個工作記憶體具備不一致性 。 為了在多執行緒環境下能實現工作記憶體中一致性,JMM定義了工作記憶體和主記憶體之間的互動操作,總共有8個原子性的互動操作

lock 鎖操作,如果執行緒對記憶體中某個變數進行了lock,在同一時間將禁止其他所有執行緒對主記憶體中該變數進行讀取操作。執行緒對應的工作記憶體和主記憶體之間禁止互動。 

unlock unlock 操作在lock操作之後執行。這是釋放鎖操作,將放開執行緒對工作記憶體中變數的讀取操作。放開執行緒對應的工作記憶體和主記憶體之間的互動。lock操作和unlock操作是成對出現的,執行多少次lock操作,就要執行相應次數的unlock操作才能完全釋放。

load load操作,是指將主記憶體中某個變數的值載入到工作記憶體中,可以看成一次記憶體轉移操作。 

read read操作和load操作成對出現,邏輯上出現在load操作之後,該操作將轉移到工作記憶體中的變數值具體複製給某個變數。read可看成是發生在工作記憶體之中的變數初始化操作,load是工作記憶體和主記憶體之間的拷貝工作,兩者配合完成一次變數讀取操作。 

use CPU使用工作記憶體中變數需要執行use操作,是定義在工作記憶體中的一種操作 assign 賦值操作,顯而意見,如果發生變數賦值操作,將執行該原子原子操作,是定義在工作記憶體中的操作。 

store 該操作和load操作是對應的操作,完成工作記憶體中內容向主記憶體中內容的轉移。 

write writer操作邏輯上發生在store操作之後,完成對主內容變數的回寫。store操作和write操作是load和read操作的對稱操作。 JVM定義的上述八種操作均是原子的,是最小操作單位,不可分割。 除此之外, 上述八個操作並不是孤立的,而是相互聯絡的,它們之間的操作必須符合下述規則: 

  1.  對主記憶體中某個變數執行lock操作,將會清空工作記憶體中該變數值。對變數執行unlock操作之前,必須將其同步到主記憶體中(store,write)。  
  2. 工作記憶體中的變數如未經過assgin操作,那麼不允許同步到主記憶體中。 
  3. load和read操作必須順序執行,但不一定需要連續執行。store和write操作也必須順序執行,但不一定需要連續執行。上述兩對操作必須形成閉環,不能只有load操作而沒有read操作。 上述的八個原子操作和相應的互動規則就是JVM對記憶體的訪問規則,掌握和理解這些規則對開發正確的多執行緒程式十分重要 

在此我向大家推薦一個架構學習交流群。交流學習群號:874811168 裡面會分享一些資深架構師錄製的視訊錄影:有Spring,MyBatis,Netty原始碼分析,高併發、高效能、分散式、微服務架構的原理,JVM效能優化、分散式架構等這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多 

————————————————

版權宣告:本文為CSDN博主「Java架構閒談」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結及本宣告。 原文連結:https://blog.csdn.net/qiyue683209/article/details/82801163


相關文章