別再混淆了!JVM內存模型和Java內存模型的本質區別
JVM 內存模型(JVM Memory Model)和 Java 內存模型(Java Memory Model, JMM)是 Java 開發中兩個非常重要的概念,但這兩個概念很容易被搞混,所以本文就來通俗易懂的講講二者的區別。
首先,我們先來看看各自的概念,以及其解決的問題。
1.JVM內存模型
- 定位:JVM 在運行 Java 程序時對物理內存的具體劃分和管理方式,用來保證 Java 程序正常執行的。
- 目的:定義 Java 程序在運行時如何分配、使用和回收內存。
- 核心組成:
a.堆(Heap):存儲對象實例(所有線程共享)。
b.方法區(Method Area):存儲類信息、常量等(JDK8 后由元空間實現)。
c.虛擬機棧(VM Stack):存儲方法的局部變量、操作數棧(每個線程私有)。
d.本地方法棧(Native Method Stack):服務于 JVM 調用本地方法。
e.程序計數器(Program Counter Register):記錄線程當前執行的指令地址。
- 關注點:內存的分配、垃圾回收(GC)、內存泄漏等問題。
JVM不劃分5大內存區域行不行?
從理論上來講可能是可行的,但從程序的運行效率、垃圾回收的效率等方面來講不劃分內存區域,所有的信息放到一起,其效率是非常慢的,是不能被允許的。
并且不劃分區域可能會導致關鍵數據易被污染的問題,例如方法區存儲的類元數據(如類結構、靜態變量)需要長期存在且全局共享,若與臨時變量混存,可能導致類信息被意外覆蓋。例如,在熱加載類時,新類元數據可能覆蓋正在被其他線程使用的舊版本,引發不可預知的錯誤。
所以綜合來看,JVM 必須按存儲的數據類型劃分為不同的數據區域,以提升程序的執行和垃圾回收的效率,并且可以減少程序在運行時的一些不必要的問題,這就是 JVM 內存模型所解決的問題。
2.Java內存模型
- 定位:Java 語言規范(JLS)定義的多線程環境下內存訪問的規則和約束的一種規范。
- 目的:解決多線程并發時的內存可見性、原子性、有序性問題,確保線程間正確通信。
- 核心概念:
a.主內存(Main Memory):所有線程共享的內存區域。
b.工作內存(Working Memory):每個線程私有的內存副本(可能對應 CPU 寄存器或緩存)。
c.happens-before原則:定義操作之間的偏序關系,確??梢娦?。
d.內存屏障(Memory Barriers):禁止指令重排序的機制。
- 關注點:如何通過 synchronized、volatile 等關鍵字或并發工具類保證線程安全。
- 示例場景:解決多線程下共享變量的不可見性(如使用 volatile 禁止指令重排序)。
PS:也就是說“Java 內存模型”主要是保證 Java 在多線程下正常運行的一種機制(或規定)。
小結
JVM內存模型 | Java內存模型(JMM) | |
范疇 | JVM 實現層面的內存區域劃分 | 多線程并發編程的內存訪問規則 |
主要目標 | 內存分配、回收和管理 | 解決線程間的可見性、有序性和原子性問題 |
具體實現 | 堆、棧、方法區等物理內存劃分 | volatile、synchronized 等語義 |