内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

JVM:晚期(運(yùn)行期)優(yōu)化的深入理解

晚期(運(yùn)行期)優(yōu)化

創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)公司,提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作,網(wǎng)頁設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);可快速的進(jìn)行網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,是專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

在部分的商用虛擬機(jī)中,Java程序最初是通過解釋器進(jìn)行解釋執(zhí)行的,當(dāng)虛擬機(jī)發(fā)現(xiàn)某個(gè)方法或代碼塊的運(yùn)行特別頻繁時(shí),就會(huì)把這些代碼認(rèn)定為熱點(diǎn)代碼。為了提高熱點(diǎn)代碼的執(zhí)行效率,在運(yùn)行時(shí),虛擬機(jī)會(huì)將這些代碼編譯成與本地平臺(tái)相關(guān)的機(jī)器碼,并進(jìn)行各種層次的優(yōu)化,完成這個(gè)任務(wù)的編譯器稱為即時(shí)編譯器

本章提到的編譯器、即時(shí)編譯器都是指HotSpot虛擬機(jī)內(nèi)的即時(shí)編譯器,虛擬機(jī)也是特質(zhì)HotSpot虛擬機(jī)

1、HotSpot虛擬機(jī)內(nèi)的即時(shí)編譯器

1)、解釋器與編譯器

當(dāng)程序需要迅速啟動(dòng)和執(zhí)行的時(shí)候,解釋器可以首先發(fā)揮作用,省去編譯的時(shí)間,立即執(zhí)行。在程序運(yùn)行后,隨著時(shí)間的推移,編譯器逐漸發(fā)揮作用,把越來越多的代碼編輯成本地代碼之后,可以獲取更高的執(zhí)行效率。當(dāng)程序運(yùn)行環(huán)境中內(nèi)存資源限制較大,可以使用解釋執(zhí)行節(jié)約內(nèi)存,反之可以使用編譯執(zhí)行來提升效率

JVM:晚期(運(yùn)行期)優(yōu)化的深入理解

HotSpot虛擬機(jī)中內(nèi)置了兩個(gè)即時(shí)編譯器,分別稱為Client Compiler和Server Compiler,或者簡稱為C1編譯器和C2編譯器。目前主流的HotSpot虛擬機(jī)中,默認(rèn)采用解釋器與其中一個(gè)編譯器直接配合的方式工作,程序使用哪個(gè)編譯器,取決于虛擬機(jī)運(yùn)行的模式,HotSpot虛擬機(jī)會(huì)根據(jù)自身版本與宿主機(jī)器的硬件性能自動(dòng)選擇運(yùn)行模式。用戶也可以使用“-client”或“-server”參數(shù)去強(qiáng)制指定虛擬機(jī)運(yùn)行在Client模式或Server模式

解釋器與編譯器搭配使用的方式在虛擬機(jī)中稱為“混合模式”,用戶可以使用參數(shù)“-Xint”強(qiáng)制虛擬機(jī)運(yùn)行于解釋模式,這時(shí)編譯器完全不介入工作,全部代碼都使用解釋方式執(zhí)行。另外,也可以使用參數(shù)“-Xcomp”強(qiáng)制虛擬機(jī)運(yùn)行于編譯模式,這時(shí)將優(yōu)先采用編譯方式執(zhí)行程序,但是解釋器仍然要在編譯無法進(jìn)行的情況下介入執(zhí)行過程,可以通過虛擬機(jī)的“-version”命令的輸出結(jié)果顯示出這3中模式

C:\Users\hxt>java -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
----------------------------------------------------------------------
C:\Users\hxt>java -Xint -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, interpreted mode)
----------------------------------------------------------------------
C:\Users\hxt>java -Xcomp -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, compiled mode)

為了在程序啟動(dòng)響應(yīng)速度與運(yùn)行效率之間達(dá)到最佳平衡,HotSpot虛擬機(jī)會(huì)啟用分層編譯的策略,分層編譯根據(jù)編譯器編譯、優(yōu)化的規(guī)模與耗時(shí),劃分出不同的編譯層次,其中包括:

  • 第0層,程序解釋執(zhí)行,解釋器不開啟性能監(jiān)控功能,可觸發(fā)第1層編譯
  • 第1層,也稱為C1編譯,將字節(jié)碼編譯為本地代碼,進(jìn)行簡單、可靠的優(yōu)化,如有必要將加入性能監(jiān)控的邏輯
  • 第2層,也稱為C2編譯,也是將字節(jié)碼編譯為本地代碼,但是會(huì)啟用一些編譯耗時(shí)較長的優(yōu)化,甚至?xí)鶕?jù)性能監(jiān)控信息進(jìn)行一些不可靠的激進(jìn)優(yōu)化

用C1編譯器獲取更高的編譯速度,用C2編譯器獲取更高的編譯質(zhì)量,在解釋執(zhí)行的時(shí)候也無須再承擔(dān)收集性能監(jiān)控信息的任務(wù)

2)、編譯對(duì)象與觸發(fā)條件

在運(yùn)行過程中會(huì)被即時(shí)編譯器編譯的熱點(diǎn)代碼有兩類:

  • 被多次調(diào)用的方法
  • 被多次執(zhí)行的循環(huán)體

對(duì)于第一種情況,由于是由方法調(diào)用觸發(fā)的編譯,因此編譯器會(huì)以整個(gè)方法作為編譯對(duì)象,這種編譯也是虛擬機(jī)標(biāo)準(zhǔn)的JIT編譯方式。而對(duì)于后一種情況,盡管編譯動(dòng)作是由循環(huán)體所觸發(fā)的,但編譯器依然會(huì)以整個(gè)方法作為編譯對(duì)象。這種編譯方式因?yàn)榫幾g發(fā)生在方法執(zhí)行過程之中,因此稱之為棧上替換(OSR編譯,即方法幀還在棧上,方法就被替換了)

判斷一段代碼是不是熱點(diǎn)代碼,是不是需要觸發(fā)即時(shí)編譯,這樣的行為稱為熱點(diǎn)探測(cè),其實(shí)進(jìn)行熱點(diǎn)探測(cè)并不一定要知道方法具體被調(diào)用了多少次,目前主要的熱點(diǎn)探測(cè)判定方式有兩種:

  • 基于采用的熱點(diǎn)探測(cè):采用這種方式的虛擬機(jī)會(huì)周期性地檢查各個(gè)線程的棧頂,如果發(fā)現(xiàn)某個(gè)方法經(jīng)常出現(xiàn)在棧頂,那這個(gè)方法就是熱點(diǎn)方法?;诓蓸拥臒狳c(diǎn)探測(cè)的好處是實(shí)現(xiàn)簡單、高效,還可以很容易地獲取方法調(diào)用關(guān)系,缺點(diǎn)是很難精確地確認(rèn)一個(gè)方法的熱度,容易因?yàn)槭艿骄€程阻塞或別的外界因素的影響而擾亂熱點(diǎn)探測(cè)
  • 基于計(jì)數(shù)器的熱點(diǎn)探測(cè):采用這種方法的虛擬機(jī)會(huì)為每個(gè)方法建立計(jì)數(shù)器,統(tǒng)計(jì)方法的執(zhí)行次數(shù),如果執(zhí)行次數(shù)超過一定的閾值就認(rèn)為它是熱點(diǎn)方法。這種統(tǒng)計(jì)方法實(shí)現(xiàn)起來麻煩一些,需要為每個(gè)方法建立并維護(hù)計(jì)數(shù)器,而且不能直接獲取到方法的調(diào)用關(guān)系,但是它的統(tǒng)計(jì)結(jié)果相對(duì)來說更加精確和嚴(yán)謹(jǐn)

在HotSpot虛擬機(jī)中使用的是基于計(jì)數(shù)器的熱點(diǎn)探測(cè),因此它為每個(gè)方法準(zhǔn)備了兩類計(jì)數(shù)器:方法調(diào)用計(jì)數(shù)器和回邊計(jì)數(shù)器

在確定虛擬機(jī)運(yùn)行參數(shù)的前提下,這兩個(gè)計(jì)數(shù)器都有一個(gè)確定的閾值,當(dāng)計(jì)數(shù)器超過閾值溢出了,就會(huì)觸發(fā)JIT編譯

方法調(diào)用計(jì)數(shù)器用于統(tǒng)計(jì)方法被調(diào)用的次數(shù),它的默認(rèn)閾值在Client模式下是1500次,在Server模式下是10000 次,這個(gè)閾值可以通過虛擬機(jī)參數(shù)-XX:CompileThreshold來設(shè)定。當(dāng)一個(gè)方法被調(diào)用時(shí),會(huì)先檢查該方法是否存在被JIT編譯過的版本,如果存在,則優(yōu)先使用編譯后的本地代碼來執(zhí)行。如果不存在已被編譯過的版本,則將此方法的調(diào)用計(jì)數(shù)器值加1,然后判斷方法調(diào)用計(jì)數(shù)器與回邊計(jì)數(shù)器值之和是否查過方法調(diào)用計(jì)數(shù)器的閾值。如果已超過閾值,那么將會(huì)向即時(shí)編譯器提交一個(gè)該方法的代碼編譯請(qǐng)求

JVM:晚期(運(yùn)行期)優(yōu)化的深入理解

如果不做任何設(shè)置,方法調(diào)用計(jì)數(shù)器統(tǒng)計(jì)的并不是方法被調(diào)用的絕對(duì)次數(shù),而是一個(gè)相對(duì)的執(zhí)行頻率,即一段時(shí)間之內(nèi)方法被調(diào)用的次數(shù)。當(dāng)超過一定的時(shí)間限度,如果方法的調(diào)用次數(shù)仍然不足以讓它提交給即時(shí)編譯器編譯,那這個(gè)方法的調(diào)用計(jì)數(shù)器就會(huì)被減少一半,這個(gè)過程稱為方法調(diào)用計(jì)數(shù)器熱度的衰減,而這段時(shí)間就稱為此方法統(tǒng)計(jì)的半衰周期。進(jìn)行熱度衰減的動(dòng)作是在虛擬機(jī)進(jìn)行垃圾收集時(shí)順便進(jìn)行的,可以使用虛擬機(jī)參數(shù)-XX: -UseCounterDecay來關(guān)閉熱度衰減,讓方法計(jì)數(shù)器統(tǒng)計(jì)方法調(diào)用的絕對(duì)次數(shù),這樣,只要系統(tǒng)運(yùn)行時(shí)間足夠長,絕大部分方法都會(huì)被編譯成本地代碼。另外,可以使用-XX:CounterHalfLifeTime參數(shù)設(shè)置半衰周期的時(shí)間,單位是秒

回邊計(jì)數(shù)器,它的作用是統(tǒng)計(jì)一個(gè)方法中循環(huán)體代碼執(zhí)行的次數(shù),在字節(jié)碼中遇到控制流向后跳轉(zhuǎn)的指令稱為 “回邊”。顯然,建立回邊計(jì)數(shù)器統(tǒng)計(jì)的目的就是為了觸發(fā)OSR編譯

關(guān)于回邊計(jì)數(shù)器的閾值,雖然HotSpot虛擬機(jī)也提供了一個(gè)類似于方法調(diào)用計(jì)數(shù)器閾值-XX:CompileThreshold的參數(shù)-XX:BackEdgeThreashold供用戶設(shè)置,但是當(dāng)前的虛擬機(jī)實(shí)際上并未使用此參數(shù),因此我們需要設(shè)置另外一個(gè)參數(shù)-XX:OnStackReplacePercentage來簡介調(diào)整回邊計(jì)數(shù)器的閾值,其計(jì)算公式如下

  • 虛擬機(jī)運(yùn)行在 Client 模式下,回邊計(jì)數(shù)器閾值計(jì)算公式為:

方法調(diào)用計(jì)數(shù)器閾值(CompileThreshold)× OSR 比率(OnStackReplacePercentage)/ 100

其中OnStackReplacePercentage默認(rèn)值為933,如果都取默認(rèn)值,那Client模式虛擬機(jī)的回邊計(jì)數(shù)器的閾值為 13995

  • 虛擬機(jī)運(yùn)行在 Server 模式下,回邊計(jì)數(shù)器閾值的計(jì)算公式為:

方法調(diào)用計(jì)數(shù)器閾值(CompileThreshold)× (OSR 比率(OnStackReplacePercentage)- 解釋器監(jiān)控比率(InterpreterProfilePercentage)) / 100

​其中OnStackReplacePercentage默認(rèn)值為140,InterpreterProfilePercentage默認(rèn)值為33,如果都取默認(rèn)值,那Server模式虛擬機(jī)回邊計(jì)數(shù)器的閾值為10700

當(dāng)解釋器遇到一條回邊指令時(shí),會(huì)先查找將要執(zhí)行的代碼片段是否有已經(jīng)編譯好的版本,如果有,它將會(huì)有限執(zhí)行已編譯的代碼,否則就把回邊計(jì)數(shù)器的值加 1,然后判斷方法調(diào)用計(jì)數(shù)器與回邊計(jì)數(shù)器之和是否超過回邊計(jì)數(shù)器的閾值。當(dāng)超過閾值的時(shí)候,將會(huì)提交一個(gè)OSR編譯請(qǐng)求,并且把回邊計(jì)數(shù)器的值降低一些,以便繼續(xù)在解釋器中執(zhí)行循環(huán),等待編譯器輸出編譯結(jié)果

JVM:晚期(運(yùn)行期)優(yōu)化的深入理解

與方法計(jì)數(shù)器不同,回邊計(jì)數(shù)器沒有計(jì)數(shù)熱度衰減的過程,因此這個(gè)計(jì)數(shù)器統(tǒng)計(jì)的就是該方法循環(huán)執(zhí)行的絕對(duì)次數(shù)。當(dāng)計(jì)數(shù)器溢出的時(shí)候,它還會(huì)把方法計(jì)數(shù)器的值也調(diào)整到溢出狀態(tài),這樣下次再進(jìn)入該方法的時(shí)候就會(huì)執(zhí)行標(biāo)準(zhǔn)編譯過程

上述內(nèi)容僅僅描述了Client VM的即時(shí)編譯方式,對(duì)于Server VM來說,執(zhí)行情況會(huì)比上面的描述更復(fù)雜一些

3)、編譯過程

在默認(rèn)設(shè)置下,無論是方法調(diào)用產(chǎn)生的即時(shí)編譯請(qǐng)求,還是OSR編譯請(qǐng)求,虛擬機(jī)在代碼編譯器還未完成之前,都仍然將按照解釋方式繼續(xù)執(zhí)行,而編譯動(dòng)作則在后臺(tái)的編譯線程中進(jìn)行。用戶可以通過參數(shù)-XX: -BackgroundCompilation來禁止后臺(tái)編譯,在禁止后臺(tái)編譯后,一旦達(dá)到JIT的編譯條件,執(zhí)行線程向虛擬機(jī)提交編譯請(qǐng)求后將會(huì)一直等待,直到編譯過程完成后再開始執(zhí)行編譯器輸出的本地代碼

對(duì)于Client Compiler來說,它是一個(gè)簡單快速的三段式編譯器,主要的關(guān)注點(diǎn)在于局部性的優(yōu)化,而放棄了許多耗時(shí)較長的全局優(yōu)化手段

在第一個(gè)階段,一個(gè)平臺(tái)獨(dú)立的前端將字節(jié)碼構(gòu)造成一種高級(jí)中間代碼表示(HIR)。HIR使用靜態(tài)單分配的形式代表代碼值,這可以使得一些在HIR的構(gòu)造過程之中和之后進(jìn)行的優(yōu)化動(dòng)作更容易實(shí)現(xiàn)。在此之前編譯器會(huì)在字節(jié)碼上完成一部分基礎(chǔ)優(yōu)化,如方法內(nèi)聯(lián)、常量傳播等優(yōu)化將會(huì)在字節(jié)碼被構(gòu)造成 HIR之前完成。

在第二個(gè)階段,一個(gè)平臺(tái)相關(guān)的后端從HIR中產(chǎn)生低級(jí)中間代碼表示(LIR),而在此之前會(huì)在HIR上完成另外一些優(yōu)化,如空值檢查消除、范圍檢查消除等,以便讓HIR達(dá)到更高效的代碼表示形式。

最后階段是在平臺(tái)相關(guān)的后端使用線性掃描算法在LIR上分配寄存器,并在LIR上做窺孔優(yōu)化,然后產(chǎn)生機(jī)器代碼

Server Compiler是專門面向服務(wù)端的典型應(yīng)用并為服務(wù)端的性能配置特別調(diào)整過的編譯器,也是一個(gè)充分優(yōu)化過的高級(jí)編譯器,還可以根據(jù)解釋器或Client Compiler提供的性能監(jiān)控信息,進(jìn)行一些不穩(wěn)定的激進(jìn)優(yōu)化

Server Compiler的寄存器分配器是一個(gè)全局圖著色分配器,它可以充分利用某些處理器架構(gòu)上的大寄存器集合

2、編譯優(yōu)化技術(shù)

1)、公共子表達(dá)式消除

如果一個(gè)表達(dá)式E已經(jīng)計(jì)算過了,并且從先前的計(jì)算到現(xiàn)在E中所有變量的值都沒有發(fā)生變化,那么E的這次出現(xiàn)就成為了公共子表達(dá)式。對(duì)于這種表達(dá)式,沒有必要花時(shí)間在對(duì)它進(jìn)行計(jì)算,只需要直接用前面計(jì)算過的表達(dá)式結(jié)果代替E就可以了。如果這種優(yōu)化僅限于程序的基本塊內(nèi),便稱為局部公共子表達(dá)式消除,如果這種優(yōu)化的范圍涵蓋了多個(gè)基本塊,那就稱為全局公共子表達(dá)式消除

2)、數(shù)組邊界檢查消除

Java語言是一門動(dòng)態(tài)安全的語言,數(shù)組邊界檢查是必須做的,但數(shù)組邊界檢查是不是必須在運(yùn)行期間一次不漏地檢查則是可以商量的事情。比如,數(shù)組下標(biāo)是一個(gè)常量,如foo[3],只要在編譯期根據(jù)數(shù)據(jù)流分析來確定foo.length的值,并判斷下標(biāo)3沒有越界,執(zhí)行的時(shí)候就無須判斷了。數(shù)組訪問發(fā)生在循環(huán)之中,并且使用循環(huán)變量來進(jìn)行數(shù)組訪問,如果編譯器只要通過數(shù)據(jù)流分析就可以判定循環(huán)變量的取值范圍永遠(yuǎn)在區(qū)間[0,foo.length)之內(nèi),那在整個(gè)循環(huán)中就可以把數(shù)組的上下界檢查消除,這可以節(jié)省很多次的條件判斷操作

隱式異常處理:Java中空指針檢查和算數(shù)運(yùn)算中除數(shù)為零的檢查都采用了隱式異常處理

if (foo != null) {
  return foo.value;
else {
  throw new NullPointException();
}

在使用隱式異常優(yōu)化之后,虛擬機(jī)會(huì)把上面?zhèn)未a所表示的訪問過程變?yōu)槿缦聜未a

try {
   return foo.value;
} catch (segment_fault) {
  uncommon_trap();
}

虛擬機(jī)會(huì)注冊(cè)一個(gè)Segment Fault信號(hào)的異常處理器(偽代碼中的uncommon_trap()),這樣當(dāng)foo不為空的Z候,對(duì)value的訪問是不會(huì)額外消耗一次對(duì)foo判空的開銷的。代價(jià)就是當(dāng)foo真的為空時(shí),必須轉(zhuǎn)入到異常處理器中恢復(fù)并拋出NullPointException異常,這個(gè)過程必須從用戶態(tài)轉(zhuǎn)到內(nèi)核態(tài)中處理,結(jié)束后再回到用戶態(tài),速度遠(yuǎn)比一次判空檢查慢。當(dāng)foo極少為空的時(shí)候,隱式異常優(yōu)化是值得的,但假如foo經(jīng)常為空的話,這樣的優(yōu)化反而會(huì)讓程序更慢,還好HotSpot虛擬機(jī)會(huì)根據(jù)運(yùn)行期收集到的 Profile 信息自動(dòng)選擇最優(yōu)方案

3)、方法內(nèi)聯(lián)

方法內(nèi)聯(lián)除了消除方法調(diào)用的成本之外,還為其他優(yōu)化手段建立良好的基礎(chǔ)

只有使用invokespecial指令調(diào)用的私有方法、實(shí)例構(gòu)造器、父類方法以及使用invokestatic指令進(jìn)行調(diào)用的靜態(tài)方法才是在編譯期進(jìn)行解析的,除了上述4中方法之外,其他的Java方法調(diào)用都需要在運(yùn)行時(shí)進(jìn)行方法接收者的多態(tài)選擇,并且都有可能存在多于一個(gè)版本的方法接收者,Java語言中默認(rèn)的實(shí)例方法是虛方法

對(duì)于一個(gè)虛方法,編譯器做內(nèi)聯(lián)的時(shí)候根本無法確定應(yīng)該使用哪個(gè)版本,為了解決虛方法的內(nèi)聯(lián)問題,引入了一種名為類型繼承關(guān)系分析(CHA)的技術(shù),這是一種基于整個(gè)應(yīng)用程序的類型分析技術(shù),它用于確定在目前已加載的類中,某個(gè)接口是否有多于一種的實(shí)現(xiàn),某個(gè)類是否存在子類、子類是否為抽象類等信息

編譯器在進(jìn)行內(nèi)聯(lián)時(shí),如果是非虛方法,那么直接進(jìn)行內(nèi)聯(lián)就可以了,這時(shí)候的內(nèi)聯(lián)是有穩(wěn)定前提保障的。如果遇到虛方法,則會(huì)向CHA查詢方法在當(dāng)前程序下是否有多個(gè)目標(biāo)版本可供選擇,如果查詢結(jié)果只有一個(gè)版本,那也可以進(jìn)行內(nèi)聯(lián),不過這種內(nèi)聯(lián)就屬于激進(jìn)優(yōu)化,需要預(yù)留一個(gè)逃生門稱為守護(hù)內(nèi)聯(lián)。如果程序的后續(xù)執(zhí)行過程中,虛擬機(jī)一直沒有加載到會(huì)令這個(gè)方法的接收者的繼承關(guān)系發(fā)生變化的類,那這個(gè)內(nèi)聯(lián)優(yōu)化的代碼就可以一直使用下去。但如果加載了導(dǎo)致繼承關(guān)系發(fā)生變化的新類,那就需要拋棄已經(jīng)編譯的代碼,退回到解釋狀態(tài)執(zhí)行,或者重新進(jìn)行編譯

如果向CHA查詢出來的結(jié)果是有多個(gè)版本的目標(biāo)方法可供選擇,編譯器使用內(nèi)聯(lián)緩存來完成方法內(nèi)聯(lián),在未發(fā)生方法調(diào)用之前,內(nèi)聯(lián)緩存狀態(tài)為空,當(dāng)?shù)谝淮握{(diào)用發(fā)生后,緩存記錄下方法接收者的版本信息,并且每次進(jìn)行方法調(diào)用時(shí)都比較接收者版本,如果以后進(jìn)來的每次調(diào)用的方法接收者版本都是一樣的,那這個(gè)內(nèi)聯(lián)還可以一直用下去。如果發(fā)生了方法接收者不一致的情況,就說明程序真正使用了虛方法的多態(tài)特性,這時(shí)才會(huì)取消內(nèi)聯(lián),查找虛方法表進(jìn)行方法分派

4)、逃逸分析

逃逸分析是為其他優(yōu)化手段提供依據(jù)的分析技術(shù)

逃逸分析的基本行為就是分析對(duì)象動(dòng)態(tài)作用域:當(dāng)一個(gè)對(duì)象在方法中被定義后,它可能被外部方法所引用,例如作為調(diào)用參數(shù)傳遞到其他方法中,稱為方法逃逸。甚至還有可能被外部線程訪問到,譬如賦值給類變量或可以在其他線程中訪問的實(shí)例變量,稱為線程逃逸

如果能證明一個(gè)對(duì)象不會(huì)逃逸到方法或線程之外,也就是別的方法或線程無法通過任何途徑訪問到這個(gè)對(duì)象,則可能為這個(gè)變量進(jìn)行一些高效的優(yōu)化:

  • 棧上分配:如果確定一個(gè)對(duì)象不會(huì)逃逸出方法之外,那讓這個(gè)對(duì)象在棧上分配內(nèi)存將會(huì)是一個(gè)很不錯(cuò)的主意,對(duì)象所占用的空間內(nèi)存就可以隨棧幀出棧而銷毀。在一般應(yīng)用中,不會(huì)逃逸的局部對(duì)象所占的比例很大,如果能使用棧上分配,那大量的對(duì)象就會(huì)隨著方法的結(jié)束而自動(dòng)銷毀了,垃圾收集系統(tǒng)的壓力將會(huì)小很多
  • 同步消除:線程同步本身是一個(gè)相對(duì)耗時(shí)的過程,如果逃逸分析能夠確定一個(gè)變量不會(huì)逃逸出線程,無法被其他線程訪問,那這個(gè)變量的讀寫肯定就不會(huì)有競(jìng)爭,對(duì)這個(gè)變量實(shí)施的同步措施也就可以消除掉
  • 標(biāo)量替換:標(biāo)量是指一個(gè)數(shù)據(jù)已經(jīng)無法再分解成更小的數(shù)據(jù)來表示了,Java虛擬機(jī)中的原始數(shù)據(jù)類型(int、long等數(shù)值類型以及reference類型等)都不能再進(jìn)一步分解,它們就可以稱為標(biāo)量。相對(duì)的,如果一個(gè)數(shù)據(jù)可以繼續(xù)分解,那它就稱作聚合量,Java中的對(duì)象就是最典型的聚合量。如果把一個(gè)Java對(duì)象拆散,根據(jù)程序訪問的情況,將其使用到的成員變量恢復(fù)原始類型來訪問就叫做標(biāo)量替換。如果逃逸分析證明一個(gè)對(duì)象不會(huì)被外部訪問,并且這個(gè)對(duì)象可以被拆散的話,那程序真正執(zhí)行的時(shí)候?qū)⒖赡懿粍?chuàng)建這個(gè)對(duì)象,而改為直接創(chuàng)建它的若干個(gè)被這個(gè)方法使用的成員變量來代替。將對(duì)象拆分后,除了可以讓對(duì)象的成員變量在棧上分配和讀寫外,還可以為后續(xù)進(jìn)一步的優(yōu)化手段創(chuàng)建條件

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)創(chuàng)新互聯(lián)的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

文章標(biāo)題:JVM:晚期(運(yùn)行期)優(yōu)化的深入理解
文章分享:http://www.rwnh.cn/article34/jesppe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、全網(wǎng)營銷推廣微信小程序、Google、網(wǎng)站導(dǎo)航App開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
乌什县| 保定市| 临邑县| 于田县| 长垣县| 延长县| 乐业县| 松溪县| 甘孜县| 高雄市| 醴陵市| 灵寿县| 涞源县| 绍兴县| 济南市| 钦州市| 若羌县| 大丰市| 辉南县| 尚义县| 临武县| 理塘县| 潢川县| 禄丰县| 巴彦淖尔市| 始兴县| 怀化市| 新沂市| 措美县| 宜川县| 胶南市| 辛集市| 海阳市| 通化县| 文水县| 黎城县| 沾化县| 化隆| 宁陕县| 多伦县| 沿河|