1. 概述
在德宏州等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供成都網(wǎng)站建設、成都做網(wǎng)站 網(wǎng)站設計制作按需開發(fā),公司網(wǎng)站建設,企業(yè)網(wǎng)站建設,成都品牌網(wǎng)站建設,營銷型網(wǎng)站,成都外貿(mào)網(wǎng)站建設公司,德宏州網(wǎng)站建設費用合理。多任務和高并發(fā)是衡量一臺計算機處理器的能力重要指標之一。一般衡量一個服務器性能的高低好壞,使用每秒事務處理數(shù)(Transactions Per Second,TPS)這個指標比較能說明問題,它代表著一秒內(nèi)服務器平均能響應的請求數(shù),而TPS值與程序的并發(fā)能力有著非常密切的關系。在討論Java內(nèi)存模型和線程之前,先簡單介紹一下硬件的效率與一致性。
2.硬件的效率與一致性
由于計算機的存儲設備與處理器的運算能力之間有幾個數(shù)量級的差距,所以現(xiàn)代計算機系統(tǒng)都不得不加入一層讀寫速度盡可能接近處理器運算速度的高速緩存(cache)來作為內(nèi)存與處理器之間的緩沖:將運算需要使用到的數(shù)據(jù)復制到緩存中,讓運算能快速進行,當運算結(jié)束后再從緩存同步回內(nèi)存之中沒這樣處理器就無需等待緩慢的內(nèi)存讀寫了。
基于高速緩存的存儲交互很好地解決了處理器與內(nèi)存的速度矛盾,但是引入了一個新的問題:緩存一致性(Cache Coherence)。在多處理器系統(tǒng)中,每個處理器都有自己的高速緩存,而他們又共享同一主存。
如下圖所示:多個處理器運算任務都涉及同一塊主存,需要一種協(xié)議可以保障數(shù)據(jù)的一致性,這類協(xié)議有MSI、MESI、MOSI及Dragon Protocol等。Java虛擬機內(nèi)存模型中定義的內(nèi)存訪問操作與硬件的緩存訪問操作是具有可比性的,后續(xù)將介紹Java內(nèi)存模型。
除此之外,為了使得處理器內(nèi)部的運算單元能竟可能被充分利用,處理器可能會對輸入代碼進行亂起執(zhí)行(Out-Of-Order Execution)優(yōu)化,處理器會在計算之后將對亂序執(zhí)行的代碼進行結(jié)果重組,保證結(jié)果準確性。與處理器的亂序執(zhí)行優(yōu)化類似,Java虛擬機的即時編譯器中也有類似的指令重排序(Instruction Recorder)優(yōu)化。
3.Java內(nèi)存模型
定義Java內(nèi)存模型并不是一件容易的事情,這個模型必須定義得足夠嚴謹,才能讓Java的并發(fā)操作不會產(chǎn)生歧義;但是,也必須得足夠?qū)捤?,使得虛擬機的實現(xiàn)能有足夠的自由空間去利用硬件的各種特性(寄存器、高速緩存等)來獲取更好的執(zhí)行速度。經(jīng)過長時間的驗證和修補,在JDK1.5發(fā)布后,Java內(nèi)存模型就已經(jīng)成熟和完善起來了。
3.1 主內(nèi)存與工作內(nèi)存
Java內(nèi)存模型的主要目標是定義程序中各個變量的訪問規(guī)則,即在虛擬機中將變量存儲到內(nèi)存和從內(nèi)存中取出變量這樣底層細節(jié)。此處的變量與Java編程時所說的變量不一樣,指包括了實例字段、靜態(tài)字段和構(gòu)成數(shù)組對象的元素,但是不包括局部變量與方法參數(shù),后者是線程私有的,不會被共享。
Java內(nèi)存模型中規(guī)定了所有的變量都存儲在主內(nèi)存中,每條線程還有自己的工作內(nèi)存(可以與前面將的處理器的高速緩存類比),線程的工作內(nèi)存中保存了該線程使用到的變量到主內(nèi)存副本拷貝,線程對變量的所有操作(讀取、賦值)都必須在工作內(nèi)存中進行,而不能直接讀寫主內(nèi)存中的變量。
不同線程之間無法直接訪問對方工作內(nèi)存中的變量,線程間變量值的傳遞均需要在主內(nèi)存來完成,線程、主內(nèi)存和工作內(nèi)存的交互關系如下圖所示,和上圖很類似。
這里的主內(nèi)存、工作內(nèi)存與Java內(nèi)存區(qū)域的Java堆、棧、方法區(qū)不是同一層次內(nèi)存劃分。
3.2 內(nèi)存間交互操作
關于主內(nèi)存與工作內(nèi)存之間的具體交互協(xié)議,即一個變量如何從主內(nèi)存拷貝到工作內(nèi)存、如何從工作內(nèi)存同步到主內(nèi)存之間的實現(xiàn)細節(jié),Java內(nèi)存模型定義了以下八種操作來完成:
1、lock(鎖定):作用于主內(nèi)存的變量,把一個變量標識為一條線程獨占狀態(tài)。
2、unlock(解鎖):作用于主內(nèi)存變量,把一個處于鎖定狀態(tài)的變量釋放出來,釋放后的變量才可以被其他線程鎖定。
3、read(讀?。鹤饔糜谥鲀?nèi)存變量,把一個變量值從主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中,以便隨后的load動作使用
4、load(載入):作用于工作內(nèi)存的變量,它把read操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中。
5、use(使用):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個變量值傳遞給執(zhí)行引擎,每當虛擬機遇到一個需要使用變量的值的字節(jié)碼指令時將會執(zhí)行這個操作。
6、assign(賦值):作用于工作內(nèi)存的變量,它把一個從執(zhí)行引擎接收到的值賦值給工作內(nèi)存的變量,每當虛擬機遇到一個給變量賦值的字節(jié)碼指令時執(zhí)行這個操作。
7、store(存儲):作用于工作內(nèi)存的變量,把工作內(nèi)存中的一個變量的值傳送到主內(nèi)存中,以便隨后的write的操作。
8、write(寫入):作用于主內(nèi)存的變量,它把store操作從工作內(nèi)存中一個變量的值傳送到主內(nèi)存的變量中。
如果要把一個變量從主內(nèi)存中復制到工作內(nèi)存,就需要按順尋地執(zhí)行read和load操作,如果把變量從工作內(nèi)存中同步回主內(nèi)存中,就要按順序地執(zhí)行store和write操作。
Java內(nèi)存模型只要求上述操作必須按順序執(zhí)行,而沒有保證必須是連續(xù)執(zhí)行。也就是read和load之間,store和write之間是可以插入其他指令的,如對主內(nèi)存中的變量a、b進行訪問時,可能的順序是read a,read b,load b, load a。Java內(nèi)存模型還規(guī)定了在執(zhí)行上述八種基本操作時,必須滿足如下規(guī)則:
1、不允許read和load、store和write操作之一單獨出現(xiàn)
2、不允許一個線程丟棄它的最近assign的操作,即變量在工作內(nèi)存中改變了之后必須同步到主內(nèi)存中。
3、不允許一個線程無原因地(沒有發(fā)生過任何assign操作)把數(shù)據(jù)從工作內(nèi)存同步回主內(nèi)存中。
4、一個新的變量只能在主內(nèi)存中誕生,不允許在工作內(nèi)存中直接使用一個未被初始化(load或assign)的變量。即就是對一個變量實施use和store操作之前,必須先執(zhí)行過了assign和load操作。
5、一個變量在同一時刻只允許一條線程對其進行l(wèi)ock操作,lock和unlock必須成對出現(xiàn)
6、如果對一個變量執(zhí)行l(wèi)ock操作,將會清空工作內(nèi)存中此變量的值,在執(zhí)行引擎使用這個變量前需要重新執(zhí)行l(wèi)oad或assign操作初始化變量的值
7、如果一個變量事先沒有被lock操作鎖定,則不允許對它執(zhí)行unlock操作;也不允許去unlock一個被其他線程鎖定的變量。
8、對一個變量執(zhí)行unlock操作之前,必須先把此變量同步到主內(nèi)存中(執(zhí)行store和write操作)。
3.3 重排序
在執(zhí)行程序時為了提高性能,編譯器和處理器經(jīng)常會對指令進行重排序。重排序分成三種類型:
1、編譯器優(yōu)化的重排序。編譯器在不改變單線程程序語義放入前提下,可以重新安排語句的執(zhí)行順序。
2、指令級并行的重排序。現(xiàn)代處理器采用了指令級并行技術來將多條指令重疊執(zhí)行。如果不存在數(shù)據(jù)依賴性,處理器可以改變語句對應機器指令的執(zhí)行順序。
3、內(nèi)存系統(tǒng)的重排序。由于處理器使用緩存和讀寫緩沖區(qū),這使得加載和存儲操作看上去可能是在亂序執(zhí)行。
從Java源代碼到最終實際執(zhí)行的指令序列,會經(jīng)過下面三種重排序:
為了保證內(nèi)存的可見性,Java編譯器在生成指令序列的適當位置會插入內(nèi)存屏障指令來禁止特定類型的處理器重排序。Java內(nèi)存模型把內(nèi)存屏障分為LoadLoad、LoadStore、StoreLoad和StoreStore四種:
以上就是Java內(nèi)存模型圖文詳解的詳細內(nèi)容,更多請關注創(chuàng)新互聯(lián)其它相關文章!
本文標題:Java中的內(nèi)存模型-創(chuàng)新互聯(lián)
當前鏈接:http://aaarwkj.com/article16/jcidg.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設計公司、虛擬主機、做網(wǎng)站、電子商務、網(wǎng)站導航、App設計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容