Java內(nèi)存模型即Java Memory Model票摇,簡稱JMM。JMM定義了Java 虛擬機(JVM)在計算機內(nèi)存(RAM)中的工作方式女气。
Java的內(nèi)存模型,采用的是共享內(nèi)存模型掉缺,線程之間的共享變量存儲在主內(nèi)存(main memory)中,每個線程都有一個私有的本地內(nèi)存(local memory)戈擒,本地內(nèi)存中存儲了該線程以讀/寫共享變量的副本攀圈。
Java內(nèi)存區(qū)域的劃分
Java內(nèi)存區(qū)域主要是指運行時數(shù)據(jù)區(qū),包括程序計數(shù)器峦甩、虛擬機棧、堆现喳、方法區(qū)凯傲、運行時常量池和本地方法棧
[圖片上傳失敗...(image-c1e913-1530195539373)]
程序計數(shù)器
程序計數(shù)器又被稱之為PC寄存器。
每個虛擬機線程都有自己的程序計數(shù)器嗦篱,用于保存虛擬機正在執(zhí)行字節(jié)碼指令的地址冰单。
虛擬機棧
每個Java虛擬機線程都有自己的私有的Java虛擬機棧,和線程同時創(chuàng)建灸促,用于存儲棧幀诫欠。
堆
堆是可供各個線程共享的運行時的內(nèi)存區(qū)域,也是供所有類實例和數(shù)組對象分配內(nèi)存的區(qū)域浴栽。
Java堆是在虛擬機啟動的時候就被創(chuàng)建荒叼,它存儲了被垃圾收集器所管理的各種對象。
方法區(qū)
方法區(qū)是可供各個線程共享的運行時的內(nèi)存區(qū)域典鸡。是用于存儲每一個類的結(jié)構(gòu)信息被廓。
運行時常量池
運行時常量池是每一個類或接口的常量池的運行時表現(xiàn)形式,包含了若干種不同的常量:從編譯器可知的數(shù)值字面量到必須運行期解析后才能獲得的方法或字段引用萝玷。
每一個運行時常量池都分配在Java虛擬機的方法之中嫁乘,在類和接口被加載到虛擬機之后,對應的常量池就被創(chuàng)建出來了球碉。
本地方法棧
本地方法棧是用于Java虛擬機存儲native方法蜓斧。如果Java虛擬機不支持native方法,可以是沒有這個本地方法棧的睁冬,如果支持本地方法棧挎春,那么這個棧一般會在線程創(chuàng)建的時候按照線程分配。
Java的內(nèi)存模型JMM
Java虛擬機規(guī)范中定義了Java內(nèi)存模型的規(guī)范豆拨,原始的Java內(nèi)存模型存在一些不足搂蜓,因此Java內(nèi)存模型在Java1.5時被重新修訂。這個版本的Java內(nèi)存模型在到現(xiàn)在仍然在使用辽装。
JMM規(guī)定了一個線程如何和何時可以看到由其他線程修改過后的共享變量的值帮碰,以及在必須時如何同步的訪問共享變量。
[圖片上傳失敗...(image-4234bd-1530195517645)]
可以在線程之間共享的內(nèi)存被稱之為堆內(nèi)存或共享內(nèi)存拾积。所有實例字段殉挽,static字段和數(shù)組元素都存儲在堆內(nèi)存中丰涉,局部變量,形式方法參數(shù)和異常處理參數(shù)絕不會再線程間共享斯碌,并且不受內(nèi)存模型的影響一死。
如果線程A與線程B之間要通信的話,必須要經(jīng)歷下面2個步驟:
1)線程A把本地內(nèi)存A中更新過的共享變量刷新到主內(nèi)存中去傻唾。
2)線程B到主內(nèi)存中去讀取線程A之前已更新過的共享變量投慈。