1. 程式人生 > 實用技巧 >Java記憶體模型總結

Java記憶體模型總結

Java記憶體模型(Java Memory Model,JMM)涉及JVM主記憶體(Main Memory)和執行緒本地記憶體(Thread Local Memory)或者稱執行緒工作記憶體。
JMM用來遮蔽Java程式在不同的硬體和作業系統上訪問記憶體的差異,定義Java程式中變數的訪問規則。

JVM的堆記憶體在主記憶體中。方法區在持久代實踐時在主記憶體中;在元空間實踐時不在主記憶體中,在直接記憶體或者稱堆外記憶體中,被作業系統直接管理。
JVM的棧或者稱虛擬機器棧、本地方法棧、程式計數器是執行緒私有的,對應記憶體線上程工作記憶體中。

主記憶體中存放類變數本體,執行緒工作記憶體可以存放類變數副本。類變數副本之間不直接互動,必須通過類變數本體作中介。

方法區域性變數只存在於執行緒工作記憶體。

8個有關主記憶體中的變數、執行緒工作記憶體中的變數的操作:
(1)lock(鎖定):主記憶體中的變數被執行緒鎖定。
(2)unlock(解鎖):主記憶體中的變數不再被執行緒鎖定。
(3)read(讀取):主記憶體中的變數的值進入執行緒工作記憶體。
(4)load(載入):進入執行緒工作記憶體的值給到執行緒工作記憶體中的變數。
(5)use(使用):操作邏輯使用執行緒工作記憶體中的變數的值。
(6)assign(賦值):操作邏輯的結果值給到執行緒工作記憶體中的變數。
(7)store(儲存):作執行緒的工作記憶體中的變數的值進入主記憶體。
(8)write(寫入):進入主記憶體的值給到主記憶體中的變數。

這8個操作遵守的規則:
(1)read和load不允許單獨使用。
(2)store和write不允許單獨使用。
(3)assign後必須store和write。
(4)沒有經過load,不允許use。
(5)沒有經過assign,不允許store。
(6)lock後必須重新load。
(7)沒有經過lock,不允許unlock。
(8)沒有經過store和write,不允許unlock。

Java記憶體模型圍繞併發中的原子性、可見性和有序性設計。
執行緒安全包括原子性、可見性、有序性。
原子性指資料操作操作不可分割。
可見性指資料操作結果被其他執行緒感知。
有序性指資料操作按序發生。

volatile自己的規則((1)、(2)保證可見性,(3)保證有序性):

(1)load和use不允許單獨使用。
(2)assign和store不允許單獨使用。
(3)假定動作A是執行緒T對變數V實施的use或assign動作,動作F是和動作A相關聯的load或store動作,動作P是和動作F相對應的對變數V的read或write動作;類似的,假定動作B是執行緒T對變數W實施的use或assign動作,動作G是和動作B相關聯的load或store動作,動作Q是和動作G相對應的對變數W的read或write動作。如果動作A先於B,那麼P先於Q。

先行發生原則:
A操作先行發生於B操作:A操作中對B操作有影響的結果能被B操作感知。
JMM中的先行發生原則:
程式次序原則:控制流前的操作先行發生於控制流後的操作。
管程鎖定規則:unlock先行發生於之後對同一個鎖的lock。
volatile變數規則:volatile變數的寫先行發生於之後對這個變數的讀。
執行緒啟動規則:Thread物件的start()方法先行發生於Thread的每個動作。
執行緒終止規則:Thread操作先行發生於執行緒的終止檢測
執行緒中斷規則:Thread的interrupt()方法先行發生於被中斷執行緒的程式碼檢測到中斷事件
物件終結規則:物件初始化方法先行發生於finalize方法
傳遞性:操作A先行發生於操作B,操作B先行發生於操作C,則操作A先行發生於操作C。

參考:

深入理解Java記憶體模型:https://www.jianshu.com/p/15106e9c4bf3

Java記憶體模型(JMM)總結:https://zhuanlan.zhihu.com/p/29881777

CPU結構、快取記憶體、匯流排鎖、快取鎖、快取一致性協議、StoreBuffer、指令重排序、記憶體屏障:https://blog.csdn.net/haoranhaoshi/article/details/108553396