深入淺出理解 | Java 內存模型

Java 內存模型

一. 硬件層面的內存模型

這裏寫圖片描述
這個圖是說明計算硬件的存儲層次(memory hierarchy)之中,寄存器(register)最快,內存其次,最慢的是硬盤。

大多數的內存運算任務都不可能只靠處理器“計算”完成,處理器需要與與內存進行交互,如讀取運算數據、存儲運算結果等,這個I/O操作很難消除。計算機的存儲設備與處理器的運算速度有幾個數量級的差距,所以現代計算機系統不得不加入一層讀寫速度極可能接近處理器運算速度的高速緩存(Cache)作爲內存與處理器之間的緩衝:將運算需要使用到的數據複製到緩存中,讓運算能夠快速的運行,運算結束後把運算結果從緩存中同步到內存中,這樣處理器就不需要等待緩慢的內存讀寫了。

但這裏有一個問題:緩存一致性(Cache Coherence)。在多處理器系統中,每個處理器都有一個自己的高速緩存,同時他們也共享同一個主內存(Main Memory), 當多個處理器運算任務同時涉及到同一塊主內存區域時,會導致各自的緩存數據不一致,那要以誰的緩存數據爲主呢?所以爲了解決這個問題,每個處理器訪問緩存時都需要遵循一些協議,在讀寫時根據協議進行操作,這些協議有MSI,MESI,MOSI,Synapse,Firefly,Dragon Protocol等。

內存模型,可以理解成在特定的操作協議下,對特定的內存或高速緩存進行讀寫訪問的過程抽象。不同架構的物理機器擁有不一樣的內存模型。這裏的內存訪問操作與硬件緩存訪問操作與Java虛擬機的內存模型很類似。

這裏寫圖片描述

除了高速緩存,爲了使處理器內部的運算單元能儘量被充分利用,處理器可能會對輸入代碼進行亂序執行(Out-Of-Order Execution)優化,處理器會在計算之後將亂序執行結果進行重組,保證該結果與順序執行的結果一致。這與Java虛擬機的即時編譯器中的指令重排序類似

二. Java的內存模型(Java Memory Model JMM)

Java的內存模型主要是爲了定義程序中各個變量的訪問規則,即在虛擬機中將變量存儲到內存和從內存中取出變量的底層細節。這裏的變量是指實例字段、靜態字段和構成數組對象的元素,但不包括局部變量與方法參數,因爲他們是線程私有的,不會被共享,自然不會存在競爭問題。

Java內存模型規定所有變量都存儲在主內存(這個只是虛擬機內存的一部分,與之前的主內存類比)中,每個線程有自己的工作內存(與之前的高速緩存類比)。線程工作內存中保存了該線程使用到的主內存中的變量副本拷貝,線程對變量的操作都是在他們的工作內存中,而不直接讀寫主內存中的變量。線程之間變量值得傳遞需通過主內存來完成。
這裏寫圖片描述

這裏我們會突然想到可不可以類比Java的內存劃分,我們把Java內存劃分拿出來類比下:
這裏寫圖片描述

這裏我們要注意內存條中,方法區和堆是所有線程共享的,而JVM棧,本地方法棧,程序計數器是線程隔離的。
Java的主內存主要對應Java堆中對象實例的部分數據,工作內存對應JVM棧中的部分區域。更底層對應整個PC的話,主內存對應主機內存條,爲了獲取更好的運行速度,虛擬機可能會讓工作內存優先存儲於寄存器和高速緩存中,因爲程序運行時主要讀寫的是工作內存。

發佈了54 篇原創文章 · 獲贊 26 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章