思考:Java內存模型和硬件內存模型

前言

前一陣在看volatile的原理,看到內存屏障和緩存一致性,發現再往底層挖就挖到了硬件和Java內存模型。這一塊是自己似懂非懂的知識區,我一般稱之為知識混沌區。因此整理這一篇文章。

什么是內存模型(Memory?Model)呢?它是系統和程序員之間的規范,它規定了存儲器訪問的行為,并影響到了性能。并且,Memory?Model有多層,處理器規定、編譯器規定、高級語。對于高級語言來說,如Java內存模型,?它通常需要支持跨平臺,也就是說它會基于各種不同的內存模型,但是又要提供給程序員一個統一的內存模型,可以理解為一個適配器的角色。

這篇文字主要包含了三部分:

  1. 硬件內存模型

  2. Java內存模型和運行時數據區

  3. 三者的關系

硬件內存模型

下圖是2012?Sandy?Bridge(一種Intel處理器)核心設計。圖中有socket1和socket2,可以理解為了這臺電腦中有兩個插cpu的槽,每個槽中有一個多核(C1,C2...Cn)的cpu。對于CPU的內存模型可以大致按照如下進行分解:

寄存器

編譯器會將本地變量和函數參數分配到這些寄存器上

內存排序緩沖(Memory?Ordering?Buffers)

這些緩沖用于記錄等待緩存子系統時正在執行的操作

L1?緩存

空間最小,訪問速度最快

L2緩存

要作用是作為L1和L3之間的高效內存訪問隊列。L2緩存同時包含數據和指令

L3緩存

在同插槽的所有核心都共享L3緩存。

主內存

在緩存完全沒命中的情況下

簡化之后如下圖所示,計算機在高速的?CPU?和相對低速的存儲設備(內存,RAM)之間使用高速緩存,作為內存和處理器之間的緩沖。將運算需要使用到的數據復制到緩存中,讓運算能快速運行,當運算結束后再從緩存同步回內存之中。

在多處理器的系統中(或者單處理器多核的系統),每個處理器內核都有自己的高速緩存,它們有共享同一主內存(Main?Memory---RAM)。

Java內存模型和運行時數據區

說完系統的內存模型,然后開始說一下Java的內存模型(Java?Memory?Model,簡稱?JMM)。

????

Java語言一大特性就是跨平臺型。其背后的實現便是在Java?虛擬機規范中定義的Java?內存模型(Java?Memory?Model,簡稱?JMM)。

虛擬機通過內存模型,定義了將變量存儲到內存和從內存中取出變量的底層細節(字節碼指令轉換是另一方面),屏蔽掉各種硬件和操作系統的內存訪問差異,實現讓?Java?程序在各種平臺下都能達到一致的內存訪問效果,不必因為不同平臺上的物理機的內存模型的差異,對各平臺定制化開發程序。

上面提到了兩個重要的概念--內存和變量。

先說內存,Java內存模型中的內存分為兩類:主內存(Main?Memory)和工作內存(Working?Memory,又稱本地內存)。其詳情如下:

主內存可以類比成物理硬件的主內存,但此處僅是虛擬機內存的部分。工作內存可以類比成處理器高速緩存

主內存是所有的線程共享,每個線程都有自己的工作內存,屬于線程私有。

一個線程不能訪問另一個線程的工作內存,線程之間需要通過主內存來實現線程間的通信;

線程的工作內存中保存了該線程使用到的變量的主內存副本拷貝,線程對變量的所有的操作(讀取、賦值等)都必須在工作內存中進行,而不能直接讀寫主內存的變量;

如果想理解上面提到的變量(Variables)的提取和存儲。那就需要繼續看一下JVM另一個重要的知識點--運行時數據區。如下圖所示,不同jdk版本的運行時數據區劃分有所差異。但主要分為了五部分:方法區(8開始使用元數據),堆,棧,程序計數器,本地方法棧。細節就不展開講。

內存模型中管理的變量(Variables)則主要指是堆中的數據,它包括了實例字段、靜態字段和構成數值對象的元素,如數組等。但不包括Java方法中局部變量與方法參數,如果局部變量是一個?reference?類型,它引用的對象在?Java?堆中可被各個線程共享,但是?reference?本身在?Java?棧的局部變量表中。

總結一下:Java?運行時數據區和內存模型是不一樣的東西,更確切的說應該是不是同一層次的東西。

  1. 內存模型:是定義了線程和主內存之間的抽象關系,更多的是定義規則

  2. 運行時數據區域:是指?JVM?運行時將數據分區域存儲,強調對內存空間的劃分。

硬件內存模型和Java內存模型關系

Java內存模型中的主內存和工作內存的區別在于線程調度和共享的區別,而不是物理層面的區別。因此硬是將Java內存模型和硬件內存模型進行映射沒有意義。如果真的有關系,只能說工作內存更多的是CPU寄存器和緩存。當然,工作內存由于上下文切換等原因,也可能會寫回RAM(可以理解為物理內存,嚴謹來說是物理虛擬內存)。

對于運行時數據區而言,有些是隨著虛擬機啟動而創建,虛擬機關閉而銷毀。還有一部分是隨著線程生命周期創建銷毀的。

線程間共享的方法區和堆,是說它們會隨著虛擬機啟動而創建,隨著虛擬機退出而銷毀。而棧和程序計數器會隨著線程開始和結束而創建和銷毀。

正如下圖所示,方法區和堆在RAM中,也可以在緩存中,這也是JVM創建時進行管理的內存空間。

以堆為例,由于對象實例的創建在JVM中非常頻繁,一方面保證并發環境下從堆區中劃分內存空間的線程安全,另一方面提升內存分配的吞吐量。對Eden區域繼續進行劃分,JVM為每個線程分配一個私有緩存區域--本地線程分配緩沖((Thread?Local?Allocation?Buffer,TLAB)。而這個緩沖則緩存中,而不是RAM中

如前所述,Java內存模型和硬件內存架構是不同的。?線程棧和堆的一部分有時可能存在于CPU高速緩存和內部CPU寄存器中。?

參考資料:

https://jenkov.com/tutorials/java-concurrency/java-memory-model.html

指令重排序 - 簡書

https://www.cnblogs.com/czwbig/p/11127124.html

https://zhuanlan.zhihu.com/p/51613784

Java 運行時數據區和內存模型(JMM)_jmm 和運行時數據區 的關系看-CSDN博客

簡單介紹一下什么是“工作內存”和“主內存”(JMM中的概念)_工作內存和主內存-CSDN博客

JVM運行時數據區------堆_數據區和堆-CSDN博客

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/42776.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/42776.shtml
英文地址,請注明出處:http://en.pswp.cn/web/42776.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CentOS6用文件配置IP模板

CentOS6用文件配置IP模板 到 CentOS6.9 , 默認還不能用 systemctl , 能用 service chkconfig sshd on 對應 systemctl enable sshd 啟用,開機啟動該服務 ### chkconfig sshd on 對應 systemctl enable sshd 啟用,開機啟動該服務 sudo chkconfig sshd onservice sshd start …

未羽研發測試管理平臺

突然有一些覺悟,程序猿不能只會吭哧吭哧的低頭做事,應該學會怎么去展示自己,怎么去宣傳自己,怎么把自己想做的事表述清楚。 于是,這兩天一直在整理自己的作品,也為接下來的找工作多做點準備。接下來…

LT7911UX 國產原裝 一拖三 edp 轉LVDS 可旋轉 可縮放

2.一般說明 該LT7911UX是一種高性能Type-C/DP1.4a到MIPI或LVDS芯片的VR/顯示應用。HDCP RX作為HDCP轉發器的上游,可以與其他芯片的HDCP TX配合實現轉發器功能。 對于DP1.4a輸入,LT7911UX可配置為1/2/4通道。自適應均衡使其適用于長電纜應用,最…

Junior.Crypt.2024 CTF Web方向 題解WirteUp 全

Buy a cat 題目描述:Buy a cat 開題 第一思路是抓包改包 Very Secure App 題目描述:All secrets become clear 開題 亂輸一個密碼就登陸成功了(不是弱口令) 但是回顯Your role is: user 但是有jwt!!&a…

深入理解基本數據結構:鏈表詳解

引言 在計算機科學中,數據結構是存儲、組織和管理數據的方式。鏈表是一種重要的線性數據結構,廣泛應用于各種編程場景。在這篇博客中,我們將詳細探討鏈表的定義、特點、操作及其在不同編程語言中的實現。 什么是鏈表? 鏈表是一種…

Mobile ALOHA前傳之VINN, Diffusion Policy和ACT對比

VINNDiffusion PolicyACT核心思想1.從離線數據中自監督學習獲得一個視覺編碼器;2.基于視覺編碼器,從采集的示例操作數據中檢索與當前觀測圖像最相似的N張圖像以及對應的動作;3.基于圖像編碼器的距離對各個動作進行加權平均,獲得最…

Open3D loss函數優化的ICP配準算法(精配準)

目錄 一、概述 1.1ICP的基本步驟 1.2損失函數的設計 二、代碼實現 2.1關鍵函數 2.2完整代碼 三、實現效果 3.1原始點云 3.2配準后點云 3.3計算數據 一、概述 ICP(Iterative Closest Point)配準算法是一種用于對齊兩個點云的經典算法。其目標是通過迭代優化…

Istio實戰教程:Service Mesh部署與流量管理

引言 Istio是一個開源的服務網格,它提供了一種統一的方法來連接、保護、控制和觀察服務。本教程將指導你從零開始部署Istio,并展示如何使用Istio進行基本的流量管理。 環境準備 Kubernetes集群:Istio運行在Kubernetes之上,確保…

W25Q64 Flash存儲器與STM32:硬件與軟件的完美結合案例

摘要 在嵌入式系統中,數據存儲是關鍵組成部分之一。W25Q64 Flash存儲器因其高容量、低功耗和高可靠性,成為STM32微控制器項目中優選的存儲解決方案。本文將展示W25Q64與STM32微控制器集成的案例,包括硬件設計、SPI通信協議實現和軟件編程策略…

記錄在Windows上安裝Docker

在Windows上安裝Docker時,可以選擇使用不同的后端。 其中兩個常見的選擇是:WSL 2(Windows Subsystem for Linux 2)和 Hyper-V 后端。此外,還可以選擇使用Windows容器。 三者的區別了解即可,推薦用WSL 2&…

我們公司落地大模型的路徑、方法和坑

我們公司落地大模型的路徑、方法和坑 李木子 AI大模型實驗室 2024年07月02日 18:35 北京 最近一年,LLM(大型語言模型)已經成熟到可以投入實際應用中了。預計到 2025 年,AI 領域的投資會飆升到 2000 億美元。現在,不只…

Thinking--在應用中添加動態水印,且不可刪除

Thinking系列,旨在利用10分鐘的時間傳達一種可落地的編程思想。 水印是一種用于保護版權和識別內容的技術,通常用于圖像、視頻或文檔中。它可以是文本、圖像或兩者的組合,通常半透明或以某種方式嵌入到內容中,使其不易被移除或篡改…

【Linux】多線程_2

文章目錄 九、多線程2. 線程的控制 未完待續 九、多線程 2. 線程的控制 主線程退出 等同于 進程退出 等同于 所有線程都退出。為了避免主線程退出,但是新線程并沒有執行完自己的任務的問題,主線程同樣要跟進程一樣等待新線程返回。 pthread_join 函數…

【代碼隨想錄_Day28】62. 不同路徑 63. 不同路徑 II

Day28 OK,今日份的打卡!第二十八天 以下是今日份的總結不同路徑不同路徑 II 以下是今日份的總結 62 不同路徑 63 不同路徑 II 今天的題目難度不低,盡量還是寫一些簡潔代碼 ^?_?^ 不同路徑 思路: 1.確定dp數組(dp…

算法學習筆記(8.2)-動態規劃入門進階

目錄 問題判斷: 問題求解步驟: 圖例: 解析: 方法一:暴力搜索 實現代碼如下所示: 解析: 方法二:記憶化搜索 代碼示例: 解析: 方法三:動態規劃 空間…

每日復盤-20240709

今日關注: 20240709 六日漲幅最大: ------1--------300391--------- 長藥控股 五日漲幅最大: ------1--------300391--------- 長藥控股 四日漲幅最大: ------1--------603155--------- 新亞強 三日漲幅最大: ------1--------301300--------- 遠翔新材 二日漲幅最大: ------1-…

基于antdesign封裝一個react的上傳組件

項目中遇到了一個上傳的需求,看了一下已有的代碼很粗糙,而且是直接引用andt的組件,體驗不太好,自己使用FormData對象封裝了一個上傳組件,僅供參考。 代碼如下: /*** FileUploadModal* description - 文件選…

Qt入門(二):Qt的基本組件

目錄 Designer程序面板 1、布局Layout 打破布局 貼合窗口 2、QWidget的屬性 3、Qlabel標簽 顯示圖片 4、QAbstractButton 按鈕類 按鈕組 5、QLineEdit 單行文本輸入框 6、ComboBox 組合框 7、若干與數字相關的組件 Designer程序面板 Qt包含了一個Designer程序 &…

Qt編程技巧總結篇(3)-信號-槽-多線程(二)

文章目錄 Qt編程技巧總結篇(3)-信號-槽-多線程(二)主進程與子線程線程同步實例與應用 小結 Qt編程技巧總結篇(3)-信號-槽-多線程(二) 多線程學習,使用QMutex,…

RTK_ROS_導航(3):點云的壓縮,PointCloud轉scan

目錄 1. 源碼的安裝2. 修改訂閱的話題3. 可視化1. 源碼的安裝 安裝過程如下 mkdir -p point_to_scan_ws/src cd point_to_scan_ws/src git clone https://github.com/BluewhaleRobot/pointcloud_to_laserscan.git cd .. catkin_make source devel/setup.bash2. 修改訂閱的話題 …