
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、基于jvm原理jmm模型和cpu緩存模型深入理解java并發(fā)編程許多以java多線程開發(fā)為主題的技術(shù)書籍,都會把對java虛擬機(jī)和java內(nèi)存模型的講解,作為講授java并發(fā)編程開發(fā)的主要內(nèi)容,有的還深化到計算機(jī)系統(tǒng)的內(nèi)存、cpu、緩存等予以解釋。事實上,在實際的java開發(fā)工作中,僅僅了解并發(fā)編程的創(chuàng)建、啟動、管理和通信等基本學(xué)問還是不夠的。一方面,假如要開發(fā)出高效、平安的并發(fā)程序,就必需深化java內(nèi)存模型和java虛擬機(jī)的工作原理,從底層了解并發(fā)編程的實質(zhì);更進(jìn)一步地,在現(xiàn)今大數(shù)據(jù)的時代,要開發(fā)出高并發(fā)、高可用、考牢靠的分布式應(yīng)用及各種中間件,更需要深化到計算機(jī)工作原理的底層去舉行代碼開
2、發(fā)。 本文嘗試以一個較為全面的角度,以java虛擬機(jī)工作原理和java內(nèi)存模型為切入,協(xié)作一些計算機(jī)cpu緩存的學(xué)問,深化理解java多線程開發(fā)中的難點(diǎn),包括線程平安和線程通信等內(nèi)容。 cpu緩存模型 規(guī)律上來說,大部分計算機(jī)系統(tǒng)的高級編程語言及其編譯器、虛擬機(jī)等構(gòu)件,都是來源于計算機(jī)硬件系統(tǒng)的原理和要求,而不是相反。java虛擬機(jī)和并發(fā)編程原理也不例外,因此第一部分先介紹一下困擾許多初學(xué)者的java多線程開發(fā)的源頭——cpu緩存模型。 計算機(jī)中,全部的計算都是在cpu寄存器中完成,而命令完成所需要的數(shù)據(jù)讀取和寫入,都需要從ram主存獵取。受硬件工藝的影
3、響,現(xiàn)在的cpu處理速度已經(jīng)遠(yuǎn)遠(yuǎn)超過主存的拜訪速度,差額基本是成千上萬的差距。 因此,cpu緩存設(shè)計應(yīng)運(yùn)而生。如下為cpu緩存架構(gòu)圖和cpu緩存與主存的速度對照: 用法cpu緩存來處理數(shù)據(jù)的步驟大致為: 1. 把需要的數(shù)據(jù)從主存復(fù)制一份到cpu緩存中; 2. cpu從緩存中讀取數(shù)據(jù)并計算; 3. 計算完成的數(shù)據(jù)刷新到主存中。 緩存全都性問題 如上的工作機(jī)制,會在多線程環(huán)境下導(dǎo)致緩存不全都的問題。為此,用法總線加鎖(已淘汰)和緩存全都性協(xié)議來解決,它大致的思想是: 當(dāng)cpu操作緩存中的數(shù)據(jù)時,假如發(fā)覺該變量是一個分享變量,意味著其它緩存中也會有這個變量的副本,然后—&
4、mdash; 1. 假如是讀操作,不做任何處理,只是從緩存中讀取數(shù)據(jù)到寄存器 2. 假如是寫操作,發(fā)出信號通知其它c(diǎn)pu將該變量的cache line置為無效狀態(tài),其它c(diǎn)pu在運(yùn)行該變量讀取的時候需要從主存更新數(shù)據(jù)。 java虛擬機(jī) 受許多資料和書籍?dāng)⑹霾粐?yán)謹(jǐn)所致,無數(shù)初學(xué)者往往容易地把java虛擬機(jī)理解為類似編譯器甚至說明器的存在,把java虛擬機(jī)當(dāng)做黑盒,認(rèn)為輸入了java源代碼,就可以輸出計算機(jī)挺直跑的程序了;由于jvm在不同操作系統(tǒng)上都有實現(xiàn),所以可以做到一份代碼,多種機(jī)器運(yùn)行的效果。這樣理解對小白或者外行人來說可能ok,但對于有主意深化學(xué)習(xí)java的小伙伴,是遠(yuǎn)遠(yuǎn)不夠的。 實際上,j
5、ava虛擬機(jī)有自己完美的硬體架構(gòu),如處理器、堆棧、寄存器等,還具有相應(yīng)的命令系統(tǒng)。包括編譯器以及jre在內(nèi)的整套體系,構(gòu)成了完整的jvm。jvm原生支持包括java、scala、kotlin在內(nèi)的語言編譯后運(yùn)行。而其中,jre又是jvm的核心部分。jre的體系結(jié)構(gòu)圖如下: 程序計數(shù)器:線程私有,每個線程都有自立的程序計數(shù)器,用于存放當(dāng)前線程接下來將要執(zhí)行的字節(jié)碼命令、分支、循環(huán)、跳轉(zhuǎn)、異樣處理等信息。 java虛擬機(jī)棧:線程私有,生命周期與線程相同。線程運(yùn)行中,執(zhí)行辦法時都會創(chuàng)建棧幀,用于存放局部變量表、操作棧、動態(tài)鏈接、辦法出口等信息。虛擬機(jī)棧的大小可以通過-xss來配置,需要特殊注重的是:
6、辦法的調(diào)用是棧幀被壓入和彈出的過程。在一定的容量之下,假如局部變量表等占用的內(nèi)存越小,則可被壓入的棧幀就越多,反之亦然。棧幀的內(nèi)存大小稱為寬度,棧幀的數(shù)量則稱為深度,兩者成反比。 本地辦法棧:線程私有,jvm為本地辦法(java native interface, c/c+實現(xiàn)的程序)所劃分的內(nèi)存區(qū)域,用于被線程調(diào)用諸如網(wǎng)絡(luò)通信、文件操作等辦法。 堆:全部線程分享,java運(yùn)行期間幾乎全部對象都存儲于此。堆內(nèi)存也會被細(xì)分為新生代、老生代等子堆。 辦法區(qū):多個線程分享,存儲那些在類的加載階段(詳見下文)已經(jīng)被jvm加載的類信息、常量、靜態(tài)變量、即時編譯器jit編譯后的代碼等數(shù)據(jù)。java8中,改
7、區(qū)的持久代內(nèi)存改為元空間。 特殊地,java程序中線程的數(shù)量,受java虛擬機(jī)棧和堆影響較大,可以粗略地認(rèn)為:一個java進(jìn)程的內(nèi)存大小=堆內(nèi)存 + 線程數(shù)量 * 線程私有棧內(nèi)存。結(jié)合操作系統(tǒng)特性,可以明確一個計算線程數(shù)量的公式:線程數(shù)=(最大地址空間maxprocessmemory - jvm堆內(nèi)存 - 系統(tǒng)保留內(nèi)存reservedosmemory)/threadstacksize(xss) jvm的類加載過程 當(dāng)java源文件經(jīng)過javac編譯完成,生成類文件之后,首先會被類加載器即classloader加載。classloader的主要職責(zé)是加載編譯好的類文件,在對應(yīng)的內(nèi)存區(qū)域中生成該類
8、的各個數(shù)據(jù)結(jié)構(gòu)。類的加載分為加載、銜接和初始化三個階段, 1. 加載:加載類的class文件 2. 銜接 2.1 驗證:確保class文件的正確性,如版本、魔術(shù)因子等 2.2 預(yù)備:為類的靜態(tài)變量分配內(nèi)存,并且初始化默認(rèn)值 2.3 解析:把類中的符號引用轉(zhuǎn)為挺直引用 3. 初始化:為類的靜態(tài)變量賦代碼編寫階段鎖賦的值 需要注重的是:類的加載實施的是懶加載,即用的時候才加載,并且在同一個運(yùn)行時包下,一個類只會被初始化一次。 類的完整的生命周期,除了類加載,還包括用法和卸載。 關(guān)于用法,jvm定義了6種主動用法類的場景,會導(dǎo)致類的加載和初始化 new對象;拜訪類的靜態(tài)變量(靜態(tài)常量不會!);拜訪類
9、的靜態(tài)辦法;用法反射;初始化子類會初始化父類;啟動類 注重初始化一個類為元素的數(shù)組不會加載類。 類加載的終于產(chǎn)物,是堆內(nèi)存中的class對象。而對于同一個classloader,不管類被加載多少次,指向的都是同一個class對象 類被加載后在棧內(nèi)存中的分布狀況 java內(nèi)存模型 通過cpu緩存和jvm工作模式的介紹,是為了引入java內(nèi)存模型的概念。java內(nèi)存模型(java memory mode, jmm)定義了jvm如何與計算機(jī)的主存舉行工作,理解jmm對正確理解java多線程開發(fā)是非常重要的。jmm模型如下圖所示: java內(nèi)存模型的工作規(guī)律,與上面介紹到的cpu緩存全都性工作規(guī)律非常
10、相像,其關(guān)于多線程的工作要點(diǎn)如下: 1. 分享變量存儲于主內(nèi)存中,每個線程都可以拜訪。 2. 每個線程都有私有的工作內(nèi)存,或稱本地內(nèi)存。這只是個規(guī)律概念,其實質(zhì)是涵蓋了寄存器、緩存、編譯器優(yōu)化和硬件等。 3. 分享變量只以副本的形式,存儲在本地內(nèi)存中。 4. 線程不能挺直操作主內(nèi)存,惟獨(dú)操作了本地內(nèi)存中的副本,才干刷新到主內(nèi)存中。 5. 每個線程也不能操作其它線程的私有的本地內(nèi)存 java線程平安的實現(xiàn) java并發(fā)編程平安需要具備的三大特性:原子性、可見性和有序性。下面將介紹,基于jmm模型和java線程平安的實現(xiàn)方式,是如何確保三大特性的。 原子性 在java并發(fā)編程中,容易的讀取和賦值操
11、作是原子性的,但是多個原子操作并在一起就不是了,比如將一個變量賦值給另外一個變量的操作。 jmm只保證了容易讀取和賦值的原子性。因此,并發(fā)編程中需要用到synchronized實現(xiàn)同步,或者用法lock接口的實現(xiàn)類加鎖;對于基本數(shù)據(jù)類型如int的自增操作,也可以用法juc包下的java.util.concurrent.atomic.*包下的原子類型。而volatile修飾的變量,不具備原子性。 可見性 基于jmm模型,對于線程讀取分享變量:首次只要從主內(nèi)存讀取到工作內(nèi)存,以后都在工作內(nèi)存中讀取即可;對于修改分享變量,新值先更新在工作內(nèi)存中,再刷新到主存中。但什么時候刷新是不確定的。因此,jav
12、a并發(fā)編程中,要確保分享變量在多線程中同步更新,可以實行如下方式: 通過synchronized關(guān)鍵字同步,可以確保在鎖釋放之前,對變量的修改刷新到主內(nèi)存中; 通過lock接口實現(xiàn)類實現(xiàn)同步,同樣可以在鎖unlock之前,把修改刷新到主內(nèi)存中; 用法volatile關(guān)鍵字,當(dāng)某線程修改了工作內(nèi)存中的分享變量副本,會挺直刷新主存中的值,并且其它線程會立即收到本地內(nèi)存中分享變量副本失效的信息,從而準(zhǔn)時從主內(nèi)存中更新值。 有序性 在jmm模型中,為了充分利用硬件性能,編譯器和命令器有可能會對程序命令舉行重排序。單線程下,這不會有什么問題,但多線程下則可能帶來意想不到的情況。 關(guān)于并發(fā)編程的有序性,jmm基于一套原生happens-before原則,來確保了多線程下一定程度的有序性。詳細(xì)說來: 程序次序規(guī)章:即便發(fā)生了重排序,在一個線程內(nèi)終于的運(yùn)行結(jié)果會與程序編寫挨次的結(jié)果全都。 鎖定規(guī)章:先unlock再lock。即一個鎖是鎖定狀態(tài),需要先解鎖才干再加鎖。 volatile規(guī)章:假如一個線程對volatile變量讀,另一個線程對該變量寫,那么寫操作一定發(fā)生在讀操作之前。 傳遞規(guī)章:假如操作a先于b,b先于c,那么a絕對先于
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 個人借款擔(dān)保人合同
- 電子商務(wù)網(wǎng)絡(luò)推廣合作免責(zé)協(xié)議
- 夫妻房屋財產(chǎn)約定協(xié)議書
- 商鋪招商代理合同
- 三農(nóng)村基層民主監(jiān)督與管理制度化方案
- 電子簽名認(rèn)證技術(shù)研究開發(fā)合作協(xié)議
- 工業(yè)地產(chǎn)租賃合同
- 油漆工種勞務(wù)分包合同
- 小學(xué)禁毒宣傳活動方案
- 樓梯口拆除改造合同
- 公司EHS知識競賽題庫附答案
- 社區(qū)健康促進(jìn)工作計劃
- 2025年度移動端SEO服務(wù)及用戶體驗優(yōu)化合同
- 中小學(xué)《清明節(jié)活動方案》班會課件
- 特殊教育學(xué)校2024-2025學(xué)年度第二學(xué)期教學(xué)工作計劃
- 寧夏銀川一中2025屆高三上學(xué)期第五次月考數(shù)學(xué)試卷(含答案)
- 2024年物聯(lián)網(wǎng)安裝調(diào)試員(初級工)職業(yè)資格鑒定考試題庫(含答案)
- 《設(shè)備科安全培訓(xùn)》課件
- 延長石油招聘筆試題庫
- 人教鄂教版六年級下冊科學(xué)全冊知識點(diǎn)
- 鄭州市地圖含區(qū)縣可編輯可填充動畫演示矢量分層地圖課件模板
評論
0/150
提交評論