Java內(nèi)存模型與JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的區(qū)別詳解
首先,這兩者是完全不同的概念,絕對(duì)不能混為一談。
1.什么是Java內(nèi)存模型?
Java內(nèi)存模型是Java語(yǔ)言在多線程并發(fā)情況下對(duì)于共享變量讀寫(xiě)(實(shí)際是共享變量對(duì)應(yīng)的內(nèi)存操作)的規(guī)范,主要是為了解決多線程可見(jiàn)性、原子性的問(wèn)題,解決共享變量的多線程操作沖突問(wèn)題。
多線程編程的普遍問(wèn)題是:
- 所見(jiàn)非所得
- 無(wú)法肉眼檢測(cè)程序的準(zhǔn)確性
- 不同的運(yùn)行平臺(tái)表現(xiàn)不同
- 錯(cuò)誤很難復(fù)現(xiàn)
故JVM規(guī)范規(guī)定了Java虛擬機(jī)對(duì)多線程內(nèi)存操作的一些規(guī)則,主要集中體現(xiàn)在volatile和synchronized這兩個(gè)關(guān)鍵字。
- volatile 是JVM提供的對(duì)共享變量在多線程讀寫(xiě)時(shí)的可見(jiàn)性保證,主要作用是對(duì)volatile修飾的共享變量禁止被緩存(這里跟CPU的高速緩存和緩存一致性協(xié)議有關(guān)),不做重排序(重排序:在CPU處理速度遠(yuǎn)大于內(nèi)存讀寫(xiě)速度的現(xiàn)狀下為了提高性能而進(jìn)行的優(yōu)化),但是并不保證共享變量操作的原子性。
- synchronized 是JVM提供的鎖機(jī)制,通過(guò)鎖的特性和內(nèi)存屏障保證鎖住區(qū)域操作的原子性、可見(jiàn)性、有序性。
- 鎖爭(zhēng)搶的是對(duì)象(static鎖的是類對(duì)象,非static鎖的是當(dāng)前對(duì)象,即this,鎖方法塊鎖的是自定義對(duì)象)在堆內(nèi)存中對(duì)象頭的一塊內(nèi)存的“主權(quán)”,只有一個(gè)線程能獲取該“主權(quán)”,即排他性,通過(guò)鎖的排他性保證對(duì)鎖住區(qū)域的操作的原子性
- 通過(guò)在代碼前后加入加載屏障(Load Barrier)和存儲(chǔ)屏障(Store Barrier),能保證鎖住代碼塊或者方法中對(duì)共享變量的操作的可見(jiàn)性
- 通過(guò)在代碼前后加入獲取屏障(Acquire Barrier)和釋放屏障(Release Barrier),能保證鎖住代碼塊或者方法中對(duì)共享變量的操作的有序性
2.什么是JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)?
JVM運(yùn)行時(shí)數(shù)據(jù)區(qū),是Java虛擬機(jī)在運(yùn)行時(shí)對(duì)該Java進(jìn)程占用的內(nèi)存進(jìn)行的一種邏輯上的劃分,包括方法區(qū)、堆內(nèi)存、虛擬機(jī)棧、本地方法棧、程序計(jì)數(shù)器。這些區(qū)塊實(shí)際都是Java進(jìn)程在Java虛擬機(jī)的運(yùn)作下通過(guò)不同數(shù)據(jù)結(jié)構(gòu)來(lái)對(duì)申請(qǐng)到的內(nèi)存進(jìn)行不同使用。
- 方法區(qū):JVM用來(lái)存儲(chǔ)加載的類信息、常量、靜態(tài)變量、編譯后的代碼等數(shù)據(jù)。不同虛擬機(jī)有不同的實(shí)現(xiàn),oracle的HotSpot在Java7中方法區(qū)放在永久代,Java8中方法區(qū)放在元空間,并通過(guò)GC機(jī)制來(lái)管理。
- 虛擬機(jī)棧:每個(gè)線程私有的空間,由多個(gè)棧幀組成,一個(gè)方法對(duì)應(yīng)一個(gè)棧幀,棧幀包括局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法返回地址、附加信息等。棧內(nèi)存默認(rèn)最大1M,超出跑出StackOverFlowError。
- 本地方法棧:類似虛擬機(jī)棧,是為虛擬機(jī)使用native本地方法而準(zhǔn)備的。具體實(shí)現(xiàn)由虛擬機(jī)廠商來(lái)實(shí)現(xiàn)。HotSpot虛擬機(jī)中實(shí)現(xiàn)與虛擬機(jī)棧一致,同時(shí)超出大小拋StackOverFlowError。
- 程序計(jì)數(shù)器:記錄當(dāng)前線程執(zhí)行字節(jié)碼的位置,存儲(chǔ)的是字節(jié)碼指令地址,如果native方法,則為空。CPU同一時(shí)間只能執(zhí)行一條線程中的指令,線程切換后通過(guò)程序計(jì)數(shù)器來(lái)恢復(fù)正確的執(zhí)行位置。
- 堆內(nèi)存:所有線程都可以訪問(wèn)修改,存放的是對(duì)象實(shí)例,是數(shù)據(jù)區(qū)中占用空間最大的部分,在HotSpot虛擬機(jī)中分為新生代和老年代,新生代又分為Eden區(qū)和Survivor0區(qū)、Survivor1區(qū)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
spring boot攔截器實(shí)現(xiàn)IP黑名單實(shí)例代碼
本篇文章主要介紹了spring boot攔截器實(shí)現(xiàn)IP黑名單實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
SpringSecurity6自定義JSON登錄的實(shí)現(xiàn)
目前最新版的Spring Boot已經(jīng)到了3.0.5了,隨之而來(lái)Spring Security 目前的版本也到了6.0.2了,Spring Security寫(xiě)法的變化特別多,本文就來(lái)介紹下,感興趣的可以了解一下2023-12-12
java基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)全局唯一ID的示例
本文主要介紹了java基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)全局唯一ID的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
一篇文章帶你入門(mén)java算術(shù)運(yùn)算符(加減乘除余,字符連接)
這篇文章主要介紹了Java基本數(shù)據(jù)類型和運(yùn)算符,結(jié)合實(shí)例形式詳細(xì)分析了java基本數(shù)據(jù)類型、數(shù)據(jù)類型轉(zhuǎn)換、算術(shù)運(yùn)算符、邏輯運(yùn)算符等相關(guān)原理與操作技巧,需要的朋友可以參考下2021-08-08
為spring get請(qǐng)求添加自定義的參數(shù)處理操作(如下劃線轉(zhuǎn)駝峰)
這篇文章主要介紹了為spring get請(qǐng)求添加自定義的參數(shù)處理操作(如下劃線轉(zhuǎn)駝峰),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
java中PriorityBlockingQueue的入隊(duì)知識(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理一篇關(guān)于java中PriorityBlockingQueue的入隊(duì)知識(shí)點(diǎn)總結(jié)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。2021-01-01
Liquibase結(jié)合SpringBoot使用實(shí)現(xiàn)數(shù)據(jù)庫(kù)管理功能
Liquibase 是一個(gè)強(qiáng)大的數(shù)據(jù)庫(kù)管理工具,它幫助你通過(guò)自動(dòng)化管理數(shù)據(jù)庫(kù)的變更、版本控制、和回滾,簡(jiǎn)化了開(kāi)發(fā)中的數(shù)據(jù)庫(kù)遷移工作,這篇文章主要介紹了Liquibase結(jié)合SpringBoot使用實(shí)現(xiàn)數(shù)據(jù)庫(kù)管理,需要的朋友可以參考下2024-12-12
IDEA中request.getParameter爆紅問(wèn)題及解決
這篇文章主要介紹了IDEA中request.getParameter爆紅問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11

