搜尋
首頁Javajava教程Java記憶體模型深度解析:總結

處理器記憶體模型

順序一致性記憶體模型是一個理論參考模型,JMM和處理器記憶體模型在設計時通常會把順序一致性記憶體模型當作參考。 JMM和處理器記憶體模型在設計時會對順序一致性模型做一些放鬆,因為如果完全按照順序一致性模型來實現處理器和JMM,那麼很多的處理器和編譯器優化都要被禁止,這對執行性能將會有很大的影響。

根據對不同類型讀/寫操作組合的執行順序的放鬆,可以把常見處理器的內存模型劃分為下面幾種類型:
放鬆程序中寫-讀操作的順序,由此產生了total store ordering記憶體模型(簡稱TSO)。
在前面1的基礎上,繼續放鬆程序中寫入-寫入操作的順序,由此產生了partial store order 記憶體模型(簡稱PSO)。
在前面1和2的基礎上,繼續放鬆程序中讀-寫和讀-讀操作的順序,由此產生了relaxed memory order內存模型(簡稱RMO)和PowerPC內存模型。

注意,這裡處理器對讀取/寫入操作的放鬆,是以兩個操作之間不存在數據依賴性為前提的(因為處理器要遵守as-if-serial語義,處理器不會對存在數據依賴性的兩個記憶體操作做重排序)。

下面的表格展示了常見處理器記憶體模型的細節特性:
記憶體模型名稱
對應的處理器
Store-Load 重排序
Store-Store重排序
Load-Load 和Load-Store重排序
可以更傳早讀取到其它處理器的寫
可以更早讀取到目前處理器的寫
TSO
sparc-TSOX64
Y
Y
PSO
sparc-PSO
Y
Y
Y Y
Y

Y
PowerPC
PowerPC
Y
Y
Y
Y
Y
在這個表格中,我們可以看到所有處理器記憶體模型都允許寫入-讀重排序,原因在第一章以說明過:它們都使用了寫入快取區,寫入快取區可能導致寫入-讀取操作重新排序。同時,我們可以看到這些處理器記憶體模型都允許更早讀到目前處理器的寫,原因同樣是因為寫快取區:由於寫入快取區僅對當前處理器可見,這個特性導致當前處理器可以比其他處理器先看到臨時保存在自己的寫入快取區中的寫入。

上面表格中的各種處理器記憶體模型,從上到下,模型由強變弱。越是追求效能的處理器,記憶體模型設計的會越弱。因為這些處理器希望記憶體模型對它們的束縛越少越好,這樣它們就可以做盡可能多的最佳化來提高效能。

由於常見的處理器記憶體模型比JMM弱,java編譯器在產生字節碼時,會在執行指令序列的適當位置插入記憶體屏障來限制處理器的重新排序。同時,由於各種處理器記憶體模型的強度並不相同,為了在不同的處理器平台向程式設計師展示一個一致的記憶體模型,JMM在不同的處理器中需要插入的記憶體屏障的數量和種類也不相同。下圖展示了JMM在不同處理器記憶體模型中需要插入的記憶體屏障的示意圖:



如上圖所示,JMM屏蔽了不同處理器記憶體模型的差異,它在不同的處理器平台之上為java程式設計師呈現了一個一致的記憶體模型。

Java記憶體模型深度解析:總結JMM,處理器記憶體模型與順序一致性記憶體模型之間的關係

JMM是一個語言級的記憶體模型,處理器記憶體模型是硬體級的記憶體模型,順序一致性記憶體模型是理論參考模型。下面是語言記憶體模型,處理器記憶體模型和順序一致性記憶體模型的強弱對比示意圖:



從上圖我們可以看出:常見的4種處理器記憶體模型比常用的3中語言記憶體模型弱,處理器記憶體模型和語言記憶體模型都比順序一致性記憶體模型弱。同處理器記憶體模型一樣,越是追求執行效能的語言,記憶體模型設計的會越弱。

JMM的設計

從JMM設計者的角度來說,在設計JMM時,需要考慮兩個關鍵因素:
程式設計師對記憶體模型的使用。程式設計師希望記憶體模型易於理解,易於編程。程式設計師希望基於一個強記憶體模型來編寫程式碼。
編譯器和處理器對記憶體模型的實作。編譯器和處理器希望記憶體模型對它們的束縛越少越好,這樣它們就可以做盡可能多的最佳化來提高效能。編譯器和處理器希望實作一個弱記憶體模型。

由於這兩個因素互相矛盾,所以JSR-133專家組在設計JMM時的核心目標就是找到一個好的平衡點:一方面要為程式設計師提供足夠強的記憶體可見度保證;另一方面,對編譯器和處理器的限制要盡可能的放鬆。以下讓我們來看看JSR-133是如何實現這一目標的。

為了具體說明,請看前面提到過的計算圓面積的範例程式碼:

double pi  = 3.14;    //A
double r   = 1.0;     //B
double area = pi * r * r; //C

上面計算圓的面積的範例程式碼存在三個happens- before關係:
A happens- before B;
B happens- before C;
A happens- before C;

由於A happens- before B,happens- before的定義會要求:A操作執行的結果要對B可見,且A操作的執行順序排在B操作之前。 但從程式語意的角度來說,對A和B做重排序即不會改變程式的執行結果,也還能提高程式的執行效能(允許這種重排序減少了對編譯器和處理器最佳化的束縛)。也就是說,上面這3個happens- before關係中,雖然2和3是必需要的,但1是不必要的。因此,JMM把happens- before要求禁止的重排序分成了下面兩類:
會改變程式執行結果的重新排序。
不會改變程式執行結果的重新排序。

JMM對這兩種不同性質的重排序,採取了不同的策略:
對於會改變程式執行結果的重新排序,JMM要求編譯器和處理器必須禁止這種重新排序。
對於不會改變程式執行結果的重新排序,JMM對編譯器和處理器不作要求(JMM允許這種重排序)。

下面是JMM的設計示意圖:

Java記憶體模型深度解析:總結

從上圖可以看出兩點:
JMM向程式設計師提供的happens- before規則能滿足程式設計師的需求。 JMM的happens- before規則不僅簡單易懂,而且也向程式設計師提供了足夠強的記憶體可見性保證(有些記憶體可見性保證其實並不一定真實存在,例如上面的A happens- before B)。
JMM對編譯器和處理器的束縛已經盡可能的少。從上面的分析我們可以看出,JMM其實是在遵循一個基本原則:只要不改變程式的執行結果(指的是單執行緒程式和正確同步的多執行緒程式),編譯器和處理器怎麼優化都行。例如,如果編譯器經過細緻的分析後,認定一個鎖只會被單一執行緒訪問,那麼這個鎖可以被消除。再例如,如果編譯器經過細緻的分析後,認定一個volatile變數僅僅只會被單一執行緒訪問,那麼編譯器可以把這個volatile變數當作一個普通變數來對待。這些最佳化既不會改變程式的執行結果,又能提高程式的執行效率。

JMM的記憶體可見性保證

Java程式的記憶體可見性保證依程式類型可分為下列三類:
單執行緒程式。單線程程式不會出現記憶體可見性問題。編譯器,runtime和處理器會共同確保單執行緒程式的執行結果與該程式在順序一致性模型中的執行結果相同。
正確同步的多執行緒程式。正確同步的多執行緒程式的執行將具有順序一致性(程式的執行結果與該程式在順序一致性記憶體模型中的執行結果相同)。這是JMM的重點,JMM透過限制編譯器和處理器的重排序來為程式設計師提供記憶體可見性保證。
未同步/未正確同步的多執行緒程式。 JMM為它們提供了最小安全性保障:執行緒執行時讀取到的值,要麼是先前某個執行緒寫入的值,要麼是預設值(0,null,false)。

下圖展示了這三類程式在JMM中與在順序一致性記憶體模型中的執行結果的異同:

Java記憶體模型深度解析:總結

只要多執行緒程式是正確同步的,JMM保證該程式在任意的處理器平台上的執行結果,與該程式在順序一致性記憶體模型中的執行結果一致。

JSR-133對舊內存模型的修補

JSR-133對JDK5之前的舊內存模型的修補主要有兩個:
增強volatile的內存語義。舊記憶體模型允許volatile變數與普通變數重排序。 JSR-133嚴格限制volatile變數與普通變數的重新排序,使volatile的寫-讀和鎖的釋放-獲取具有相同的記憶體語義。
增強final的記憶語語義。在舊記憶體模型中,多次讀取同一個final變數的值可能會不相同。為此,JSR-133為final增加了兩個重排序規則。現在,final具有了初始化安全性。

 以上就是Java記憶體模型深度解析:總結的內容,更多相關內容請關注PHP中文網(www.php.cn)!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?Mar 17, 2025 pm 05:46 PM

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?Mar 17, 2025 pm 05:44 PM

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?Mar 17, 2025 pm 05:43 PM

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Mar 17, 2025 pm 05:35 PM

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。