Java內存模型相關知識總結
【1】CPU和緩存的一致性

我們應該都知道,計算機在執(zhí)行程序的時候,每條指令都是在CPU中執(zhí)行的,而執(zhí)行的時候,又免不了要和數(shù)據(jù)打交道。而計算機上面的數(shù)據(jù),是存放在主存當中的,也就是計算機的物理內存啦。
剛開始,還相安無事的,但是隨著CPU技術的發(fā)展,CPU的執(zhí)行速度越來越快。而由于內存的技術并沒有太大的變化,所以從內存中讀取和寫入數(shù)據(jù)的過程和CPU的執(zhí)行速度比起來差距就會越來越大,這就導致CPU每次操作內存都要耗費很多等待時間。
所以,人們想出來了一個好的辦法,就是在CPU和內存之間增加高速緩存。緩存的概念大家都知道,就是保存一份數(shù)據(jù)拷貝。他的特點是速度快,內存小,并且昂貴。
那么,程序的執(zhí)行過程就變成了:
當程序在運行過程中,會將運算需要的數(shù)據(jù)從主存復制一份到CPU的高速緩存當中,那么CPU進行計算時就可以直接從它的高速緩存讀取數(shù)據(jù)和向其中寫入數(shù)據(jù),當運算結束之后,再將高速緩存中的數(shù)據(jù)刷新到主存當中。
在CPU和主存之間增加緩存,在多線程場景下就可能存在緩存一致性問題,也就是說,在多核CPU中,每個核的自己的緩存中,關于同一個數(shù)據(jù)的緩存內容可能不一致。
【2】處理器優(yōu)化和指令重排
上面提到在在CPU和主存之間增加緩存,在多線程場景下會存在緩存一致性問題。除了這種情況,還有一種硬件問題也比較重要。那就是為了使處理器內部的運算單元能夠盡量的被充分利用,處理器可能會對輸入代碼進行亂序執(zhí)行處理。這就是處理器優(yōu)化。
除了現(xiàn)在很多流行的處理器會對代碼進行優(yōu)化亂序處理,很多編程語言的編譯器也會有類似的優(yōu)化,比如Java虛擬機的即時編譯器(JIT)也會做指令重排。
可想而知,如果任由處理器優(yōu)化和編譯器對指令重排的話,就可能導致各種各樣的問題。
解決方法:內存屏障
【3】什么是Java內存模型
內存模型
為了保證共享內存的正確性(可見性、有序性、原子性),內存模型定義了共享內存系統(tǒng)中多線程程序讀寫操作行為的規(guī)范。通過這些規(guī)則來規(guī)范對內存的讀寫操作,從而保證指令執(zhí)行的正確性。
Java內存模型(Java Memory Model,JMM)是java虛擬機規(guī)范定義的,用來屏蔽掉java程序在各種不同的硬件和操作系統(tǒng)對內存的訪問的差異,這樣就可以實現(xiàn)java程序在各種不同的平臺上都能達到內存訪問的一致性。

Java內存模型的主要目標是定義程序中變量的訪問規(guī)則。即在虛擬機中將變量存儲到主內存或者將變量從主內存取出這樣的底層細節(jié)。需要注意的是這里的變量跟我們寫java程序中的變量不是完全等同的。這里的變量是指實例字段,靜態(tài)字段,構成數(shù)組對象的元素,但是不包括局部變量和方法參數(shù)(因為這是線程私有的)。
Java內存模型中涉及到的概念有:
主內存:java虛擬機規(guī)定所有的變量(不是程序中的變量)都必須在主內存中產生。可以與前面說的物理機的主內存相比,只不過物理機的主內存是整個機器的內存,而虛擬機的主內存是虛擬機內存中的一部分。
工作內存:java虛擬機中每個線程都有自己的工作內存,該內存是線程私有的??梢耘c前面說的高速緩存相比。線程的工作內存保存了線程需要的變量在主內存中的副本。虛擬機規(guī)定,線程對主內存變量的修改必須在線程的工作內存中進行,不能直接讀寫主內存中的變量。不同的線程之間也不能相互訪問對方的工作內存。如果線程之間需要傳遞變量的值,必須通過主內存來作為中介進行傳遞。
工作內存和主內存的劃分和 Java 堆,棧,方法區(qū)的劃分不同,兩者基本沒有關系,如果勉強對應,則主內存可理 解為堆中實例數(shù)據(jù)部分,工作內存則對應棧中部分區(qū)域
【4】volatile的內存語義
volatile寫的內存語義:
當寫一個變量的時候,JMM會把該線程的私有內存中的共享變量值更新到主內存中,并將其他線程中的值置為無效的;
volatile讀的內存語義:
當讀一個變量的時候,JMM會先判斷是否私有空間內的值是否失效,若失效,線程接下來會從主存中讀取變量。
【5】鎖的內存語義
當線程釋放鎖時,JMM會把該線程對應的本地內存中的共享變量刷新到主內存中。
當線程獲取鎖時,JMM會把該線程對應的本地內存置為無效。從而使得被監(jiān)視器保護的臨界區(qū)代碼必須要從主內存中去讀取共享變量。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
java實現(xiàn)日歷(某年的日歷,某月的日歷)用戶完全自定義
本篇文章介紹了,java實現(xiàn)日歷(某年的日歷,某月的日歷)用戶完全自定義。需要的朋友參考下2013-05-05
tio-http-server打包為二進制文件的實現(xiàn)及優(yōu)勢詳解
這篇文章主要為大家介紹了tio-http-server打包為二進制文件實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12

