- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- Java內存模型的原理是什么
這篇文章將為大家詳細講解有關(guān)Java內存模型的原理是什么,文章內容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
所有的編程語(yǔ)言中都有內存模型這個(gè)概念,區別于微架構的內存模型,高級語(yǔ)言的內存模型包括了編譯器和微架構兩部分。我試圖了解了Java、C#和Go語(yǔ)言的內存模型,發(fā)現內容基本大同小異,只是這些語(yǔ)言在具體實(shí)現的時(shí)候略有不同。
我們來(lái)看看Java內存模型吧,提到Java內存模型大家對這個(gè)圖一定非常熟悉:
這張圖告訴我們在線(xiàn)程運行的時(shí)候有一個(gè)內存專(zhuān)用的一小塊內存,當Java程序會(huì )將變量同步到線(xiàn)程所在的內存,這時(shí)候會(huì )操作工作內存中的變量,而線(xiàn)程 中變量的值何時(shí)同步回主內存是不可預期的。但同時(shí)Java內存模型又告訴我們通過(guò)使用關(guān)鍵詞“synchronized”或“volatile”可以讓 Java保證某些約束:
“volatile” — 保證讀寫(xiě)的都是主內存的變量
“synchronized” — 保證在塊開(kāi)始時(shí)都同步主內存的值到工作內存,而塊結束時(shí)將變量同步回主內存
通過(guò)以上描述我們就可以寫(xiě)出線(xiàn)程安全的Java程序,JDK也同時(shí)幫我們屏蔽了很多底層的東西。
但當你深入了解JVM的時(shí)候你會(huì )發(fā)現根本就沒(méi)有工作內存這個(gè)東西,即內存中根本不會(huì )分配這么一塊空間來(lái)運行你的Java程序,那么工作內存到底是什么東西呢?
這個(gè)問(wèn)題也曾經(jīng)困擾了我很長(cháng)時(shí)間,因為我從來(lái)沒(méi)有從JVM的實(shí)現中找到過(guò)和主內存同步的代碼,因為當使用“volatile”時(shí)我僅僅能從源代碼中調用了這行語(yǔ)句:
__asm__ volatile ("lock; addl $0,0(%%esp)" : : : "cc", "memory");
而這個(gè)指令在部分微架構上的主要功能就是防止指令重排,即這條指令前后的其它指令不會(huì )越過(guò)這個(gè)界限執行[注1]。
在現在的x86/x64微架構中讀寫(xiě)內存的一致性都是通過(guò)MESI(Intel使用MESI-F,AMD使用MOESI)協(xié)議保證[注2],MESI的狀態(tài)轉換圖如下:
更詳細的中文文檔描述可以查看這個(gè)文檔:http://blog.csdn.net/zhuliting/article/details/6210921
那Java內存模型中所說(shuō)的工作內存是什么呢?
我的理解是,首先“工作內存”是一個(gè)虛擬的概念,而承載這個(gè)概念主要是兩部分:
1. 編譯器
2. 微架構
作為編譯器肯定是執行速度越快越好,所以作為編譯器應當盡量減少從內存讀數據,如果一個(gè)數據在寄存器中,那么直接使用寄存器中的值無(wú)疑性能是*** 的,但同時(shí)這也會(huì )導致可能讀不到***的值,這里我們通過(guò)在Java語(yǔ)言中為變量加上“volatile”強制告訴編譯器這個(gè)變量一定要從內存獲得,這時(shí)編 譯器即不會(huì )做此類(lèi)優(yōu)化【案例見(jiàn)參考資料5(是一個(gè).Net的例子)】。
對于微架構來(lái)說(shuō),在x86/x64下,CPU會(huì )在執行指令時(shí)做指令重排,即編譯器生成的指令順序和真正在CPU執行的順序可能是不一致的。當我們用一個(gè)變量做信號的時(shí)候這種指令重排會(huì )帶來(lái)悲劇,即如果有如下代碼:
x = 0; y = 0; i = 0; j = 0; // thread A y = 1; x = 1; // thread B i = x; j = y;
上面的代碼i和j的值會(huì )是多少呢?答案是:“00, 01, 10, 11”都是有可能的。
對于這種情況,如果我們想得到確定的結果則需要通過(guò)“synchronized”(或者j.c.u.locks)來(lái)做線(xiàn)程間同步。
所以,我個(gè)人對Java內存模型的理解是:在編譯器各種優(yōu)化及多種類(lèi)型的微架構平臺上,Java語(yǔ)言規范制定者試圖創(chuàng )建一個(gè)虛擬的概念并傳遞到 Java程序員,讓他們能夠在這個(gè)虛擬的概念上寫(xiě)出線(xiàn)程安全的程序來(lái),而編譯器實(shí)現者會(huì )根據Java語(yǔ)言規范中的各種約束在不同的平臺上達到Java程序 員所需要的線(xiàn)程安全這個(gè)目的。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站