CodeGym/Java Course/Module 3 a ɛto so abien/JVM 中的內存,第 2 部分

JVM 中的內存,第 2 部分

開放

內存硬件架構

現代內存硬件架構不同於 Java 的內部內存模型。因此,您需要了解硬件體系結構才能了解 Java 模型如何與它一起工作。本節介紹一般內存硬件架構,下一節介紹 Java 如何使用它。

這是現代計算機硬件架構的簡化圖:

內存硬件架構

在現代世界,一台計算機有 2 個或更多處理器,這已經是常態。其中一些處理器可能還具有多個內核。在這樣的計算機上,可以同時運行多個線程。每個處理器核心都能夠在任何給定時間執行一個線程。這意味著任何 Java 應用程序都是先驗多線程的,並且在您的程序中,每個處理器內核可以同時運行一個線程。

處理器內核包含一組駐留在其內存中(內核內部)的寄存器。它對寄存器數據執行操作的速度比對駐留在計算機主內存 (RAM) 中的數據快得多。這是因為處理器可以更快地訪問這些寄存器。

每個 CPU 也可以有自己的緩存層。大多數現代處理器都有它。處理器訪問其高速緩存的速度比主存快得多,但不如其內部寄存器快。高速緩存訪問速度的值大約介於主存儲器和內部寄存器的訪問速度之間。

此外,處理器有一個地方可以擁有多級緩存。但是為了理解 Java 內存模型如何與硬件內存交互,了解這一點並不重要。重要的是要知道處理器可能具有某種級別的高速緩存。

任何計算機也以相同的方式包含 RAM(主內存區域)。所有內核都可以訪問主內存。主內存區域通常比處理器內核的緩存內存大得多。

在處理器需要訪問主內存的那一刻,它會將其中的一部分讀入其高速緩存中。它還可以從緩存中讀取一些數據到其內部寄存器中,然後對其進行操作。當 CPU 需要將結果寫回主存時,它會將數據從其內部寄存器刷新到高速緩存,並在某個時候刷新到主存。

當處理器需要在緩存中存儲其他內容時,存儲在緩存中的數據通常會刷新回主內存。緩存具有清除內存和同時寫入數據的能力。處理器不需要在每次更新期間都讀取或寫入完整的緩存。通常緩存在小塊內存中更新,它們被稱為“緩存行”。一個或多個“高速緩存行”可被讀入高速緩存存儲器,並且一個或多個高速緩存行可被刷新回主存儲器。

結合Java內存模型和內存硬件架構

正如已經提到的,Java 內存模型和內存硬件架構是不同的。硬件架構不區分線程棧和堆。在硬件上,線程堆棧和 HEAP(堆)駐留在主內存中。

部分堆棧和線程堆有時可能會出現在 CPU 的高速緩存和內部寄存器中。如圖所示:

線程堆棧和堆

當對象和變量可以存儲在計算機內存的不同區域時,就會出現某些問題。這是兩個主要的:

  • 線程對共享變量所做更改的可見性。
  • 讀取、檢查和寫入共享變量時的競爭條件。

下面將對這兩個問題進行解釋。

共享對象的可見性

如果兩個或多個線程在沒有正確使用 volatile 聲明或同步的情況下共享一個對象,則一個線程對共享對象所做的更改可能對其他線程不可見。

想像一下,一個共享對象最初存儲在主內存中。在一個 CPU 上運行的線程將共享對象讀入同一個 CPU 的緩存中。他在那裡對對象進行了更改。在 CPU 的緩存被刷新到主內存之前,共享對象的修改版本對運行在其他 CPU 上的線程是不可見的。這樣,每個線程都可以獲得自己的共享對象副本,每個副本都會在單獨的 CPU 緩存中。

下圖說明了這種情況的概要。運行在左側 CPU 上的一個線程將共享對象複製到它的緩存中,並將 count 的值更改為 2。此更改對於運行在右側 CPU 上的其他線程是不可見的,因為對 count 的更新尚未刷新回主內存。

要解決這個問題,可以在聲明變量時使用volatile關鍵字。它可以確保給定的變量直接從主存中讀取,並且在更新時總是寫回主存。

競爭條件

如果兩個或多個線程共享同一個對象並且多個線程更新該共享對像中的變量,則可能會出現競爭條件。

假設線程 A 將共享對象的計數變量讀入其處理器的緩存中。還想像一下線程 B 做同樣的事情,但是在另一個處理器的緩存中。現在線程 A 將 count 的值加 1,線程 B 也做同樣的事情。現在變量已經增加了兩次 - 在每個處理器的緩存中分別增加了 +1。

如果按順序執行這些增量,則計數變量將加倍並寫回主內存(原始值 + 2)。

但是,在沒有適當同步的情況下同時執行了兩個增量。無論哪個線程(A 或 B)將其更新版本的 count 寫入主存,新值只會比原始值多 1,儘管增加了兩次。

此圖說明了上述競爭條件問題的發生:

要解決這個問題,可以使用 Java 同步塊。同步塊確保在任何給定時間只有一個線程可以進入給定的代碼關鍵部分。

同步塊還保證所有在同步塊內部訪問的變量都會從主存中讀取,並且當線程退出同步塊時,所有更新的變量都會被刷新回主存,不管變量是聲明為volatile還是否。

留言
  • 受歡迎
你必須登入才能留言
此頁面尚無留言