Java-內(nèi)存模型知識

Java內(nèi)存模型的抽象結(jié)構(gòu)

一棘催、 運行時內(nèi)存的劃分

先談一下運行時數(shù)據(jù)區(qū),下面這張圖相信大家一點都不陌生:


對于每一個線程來說倍宾,棧都是私有的雏节,而堆是共有的。

也就是說在棧中的變量(局部變量高职、方法定義參數(shù)钩乍、異常處理器參數(shù))不會在線程之間共享,也就不會有內(nèi)存可見性(下文會說到)的問題怔锌,也不受內(nèi)存模型的影響寥粹。而在堆中的變量是共享的,本文稱為共享變量埃元。

所以涝涤,內(nèi)存可見性是針對的共享變量

二岛杀、既然堆是共享的阔拳,為什么在堆中會有內(nèi)存不可見問題?

這是因為現(xiàn)代計算機為了高效类嗤,往往會在高速緩存區(qū)中緩存共享變量糊肠,因為cpu訪問緩存區(qū)比訪問內(nèi)存要快得多辨宠。

線程之間的共享變量存在主內(nèi)存中,每個線程都有一個私有的本地內(nèi)存货裹,存儲了該線程以讀嗤形、寫共享變量的副本。本地內(nèi)存是Java內(nèi)存模型的一個抽象概念弧圆,并不真實存在赋兵。它涵蓋了緩存、寫緩沖區(qū)搔预、寄存器等霹期。

Java線程之間的通信由Java內(nèi)存模型(簡稱JMM)控制,從抽象的角度來說斯撮,JMM定義了線程和主內(nèi)存之間的抽象關(guān)系经伙。JMM的抽象示意圖如圖所示:


從圖中可以看出: 1. 所有的共享變量都存在主內(nèi)存中扶叉。 2. 每個線程都保存了一份該線程使用到的共享變量的副本勿锅。 3. 如果線程A與線程B之間要通信的話,必須經(jīng)歷下面2個步驟: 1. 線程A將本地內(nèi)存A中更新過的共享變量刷新到主內(nèi)存中去枣氧。 2. 線程B到主內(nèi)存中去讀取線程A之前已經(jīng)更新過的共享變量溢十。

所以,線程A無法直接訪問線程B的工作內(nèi)存达吞,線程間通信必須經(jīng)過主內(nèi)存张弛。

注意,根據(jù)JMM的規(guī)定酪劫,線程對共享變量的所有操作都必須在自己的本地內(nèi)存中進行吞鸭,不能直接從主內(nèi)存中讀取

所以線程B并不是直接去主內(nèi)存中讀取共享變量的值覆糟,而是先在本地內(nèi)存B中找到這個共享變量刻剥,發(fā)現(xiàn)這個共享變量已經(jīng)被更新了,然后本地內(nèi)存B去主內(nèi)存中讀取這個共享變量的新值滩字,并拷貝到本地內(nèi)存B中造虏,最后線程B再讀取本地內(nèi)存B中的新值。

那么怎么知道這個共享變量的被其他線程更新了呢麦箍?這就是JMM的功勞了漓藕,也是JMM存在的必要性之一。JMM通過控制主內(nèi)存與每個線程的本地內(nèi)存之間的交互挟裂,來提供內(nèi)存可見性保證享钞。

Java中的volatile關(guān)鍵字可以保證多線程操作共享變量的可見性以及禁止指令重排序,synchronized關(guān)鍵字不僅保證可見性诀蓉,同時也保證了原子性(互斥性)栗竖。在更底層寝姿,JMM通過內(nèi)存屏障來實現(xiàn)內(nèi)存的可見性以及禁止重排序。為了程序員的方便理解划滋,提出了happens-before饵筑,它更加的簡單易懂,從而避免了程序員為了理解內(nèi)存可見性而去學(xué)習(xí)復(fù)雜的重排序規(guī)則以及這些規(guī)則的具體實現(xiàn)方法处坪。

三根资、JMM與Java內(nèi)存區(qū)域劃分的區(qū)別與聯(lián)系

上面兩小節(jié)分別提到了JMM和Java運行時內(nèi)存區(qū)域的劃分,這兩者既有差別又有聯(lián)系:

  • 區(qū)別

    兩者是不同的概念層次同窘。JMM是抽象的玄帕,他是用來描述一組規(guī)則,通過這個規(guī)則來控制各個變量的訪問方式想邦,圍繞原子性裤纹、有序性、可見性等展開的丧没。而Java運行時內(nèi)存的劃分是具體的鹰椒,是JVM運行Java程序時,必要的內(nèi)存劃分呕童。

  • 聯(lián)系

    都存在私有數(shù)據(jù)區(qū)域和共享數(shù)據(jù)區(qū)域漆际。一般來說,JMM中的主內(nèi)存屬于共享數(shù)據(jù)區(qū)域夺饲,他是包含了堆和方法區(qū)奸汇;同樣,JMM中的本地內(nèi)存屬于私有數(shù)據(jù)區(qū)域往声,包含了程序計數(shù)器擂找、本地方法棧、虛擬機棧浩销。

實際上贯涎,他們表達的是同一種含義,這里不做區(qū)分撼嗓。

更多詳細關(guān)于JMM的知識的可參考:
JVM—認(rèn)識JVM的內(nèi)存布局和運行時數(shù)據(jù)區(qū)
Java內(nèi)存模型(JMM)詳解柬采,java語言入門知識

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市且警,隨后出現(xiàn)的幾起案子粉捻,更是在濱河造成了極大的恐慌,老刑警劉巖斑芜,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肩刃,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機盈包,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門沸呐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呢燥,你說我怎么就攤上這事崭添。” “怎么了叛氨?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵呼渣,是天一觀的道長。 經(jīng)常有香客問我寞埠,道長屁置,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任仁连,我火速辦了婚禮蓝角,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘饭冬。我一直安慰自己使鹅,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布伍伤。 她就那樣靜靜地躺著并徘,像睡著了一般遣钳。 火紅的嫁衣襯著肌膚如雪扰魂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天蕴茴,我揣著相機與錄音劝评,去河邊找鬼。 笑死倦淀,一個胖子當(dāng)著我的面吹牛蒋畜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播撞叽,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼姻成,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了愿棋?” 一聲冷哼從身側(cè)響起科展,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎糠雨,沒想到半個月后才睹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年琅攘,在試婚紗的時候發(fā)現(xiàn)自己被綠了垮庐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡坞琴,死狀恐怖哨查,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情剧辐,我是刑警寧澤解恰,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站浙于,受9級特大地震影響护盈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜羞酗,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一腐宋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧檀轨,春花似錦胸竞、人聲如沸参萄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至筒溃,卻和暖如春马篮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怜奖。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工浑测, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留歪玲,地道東北人迁央。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓滥崩,卻偏偏與公主長得像岖圈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子夭委,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容