《深入理解 Java 虛擬機(jī)》學(xué)習(xí) -- Java 內(nèi)存模型
1. 區(qū)別
這里要和 JVM 內(nèi)存模型區(qū)分開來:
- JVM 內(nèi)存模型是指 JVM 內(nèi)存分區(qū)
- Java 內(nèi)存模型(JMM)是指一種虛擬機(jī)規(guī)范
2. 目的
緩存一致性
在硬件中意述,為了解決處理器與內(nèi)存的速度矛盾,在兩者之間使用了高速緩存叙凡,但也引入了新的問題:緩存一致性涎跨。
在多處理器系統(tǒng)中汪榔,每個處理器都有自己的高速緩存悦荒,而它們又共享同一主內(nèi)存春锋。當(dāng)多個處理器的運(yùn)算任務(wù)都涉及同一塊主內(nèi)存區(qū)域時(shí)累贤,將可能導(dǎo)致各自的緩存數(shù)據(jù)不一致的情況。
為了解決一致性問題屹耐,需要各個處理器訪問緩存時(shí)都遵循一些協(xié)議尸疆,這便是緩存一致性。
總結(jié):
Java 內(nèi)存模塊是用來屏蔽掉各種硬件和操作系統(tǒng)的內(nèi)存訪問差異张症,以實(shí)現(xiàn)讓 Java 程序在各種平臺下都能達(dá)到一致的并發(fā)效果仓技。
3. 主內(nèi)存和工作內(nèi)存
Java 內(nèi)存模型的主要目標(biāo)是定義程序中各個變量的訪問規(guī)則鸵贬,即在虛擬機(jī)中將變量存儲到內(nèi)存和從內(nèi)存中取出變量這樣的底層細(xì)節(jié)俗他。
- Java 內(nèi)存模型規(guī)定了所有的變量都存儲在主內(nèi)存中,每個線程有自己的工作內(nèi)存阔逼。
- 線程的工作內(nèi)存中保存了被該線程使用到的變量的主內(nèi)存副本拷貝兆衅,線程對變量的所有操作(讀取,賦值等)都必須在工作內(nèi)存中進(jìn)行嗜浮,而不能直接讀寫主內(nèi)存中的變量羡亩。不同線程之間也無法發(fā)直接訪問對方工作內(nèi)存中的變量,線程間變量值的傳遞均需要通過主內(nèi)存來完成危融。
線程畏铆,主內(nèi)存,工作內(nèi)存三者的交互關(guān)系:
4. 內(nèi)存間交互操作
關(guān)于主內(nèi)存與工作內(nèi)存之間具體的交互協(xié)議吉殃,即一個變量如何從主內(nèi)存拷貝到工作內(nèi)存辞居、如何從工作內(nèi)存同步回主內(nèi)存之類的實(shí)現(xiàn)細(xì)節(jié),Java 內(nèi)存模型中定義了八種操作來完成蛋勺,這里只講解四種:
- read(讀韧咴睢):作用于主內(nèi)存的變量,它把一個變量的值從主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中抱完,以便隨后的 load 動作使用贼陶。
- load(載入):作用于工作內(nèi)存的變量,它把 read 操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中巧娱。
- store(存儲):作用于工作內(nèi)存的變量碉怔,它把工作內(nèi)存中一個變量的值傳送到主內(nèi)存中,以便隨后的 write 操作使用
- write(寫入):作用于主內(nèi)存的變量禁添,它把 store 操作從工作內(nèi)存中得到的變量的值放入主內(nèi)存的變量中
注意:
- 如果要把一個變量從主內(nèi)存復(fù)制到工作內(nèi)存撮胧,那就要按順序地執(zhí)行 read 和 load 操作,如果要把變量從工作內(nèi)存同步回主內(nèi)存上荡,就要按順序地執(zhí)行 store 和 write 操作趴樱。
- Java 內(nèi)存模型只要求上述兩個操作必須按順序執(zhí)行馒闷,而沒有保證必須是連續(xù)執(zhí)行。即 read 與 load 之間叁征、store 和 write 之間是可插入其他指令的纳账。