日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

淺談JVM運(yùn)行期的幾種優(yōu)化手段

來(lái)源: 責(zé)編: 時(shí)間:2024-03-18 09:42:36 169觀看
導(dǎo)讀一、摘要在之前的文章中我們談到過(guò),相比 C/C++ 語(yǔ)言,Java 語(yǔ)言在運(yùn)行效率方面要稍遜一些,因?yàn)?Java 應(yīng)用程序是在虛擬機(jī)上運(yùn)行,而 C/C++ 程序是直接編譯成平臺(tái)相應(yīng)的機(jī)器碼來(lái)運(yùn)行程序。從虛擬機(jī)對(duì)外發(fā)布開(kāi)始,開(kāi)發(fā)團(tuán)隊(duì)一直

一、摘要

在之前的文章中我們談到過(guò),相比 C/C++ 語(yǔ)言,Java 語(yǔ)言在運(yùn)行效率方面要稍遜一些,因?yàn)?Java 應(yīng)用程序是在虛擬機(jī)上運(yùn)行,而 C/C++ 程序是直接編譯成平臺(tái)相應(yīng)的機(jī)器碼來(lái)運(yùn)行程序。OCv28資訊網(wǎng)——每日最新資訊28at.com

從虛擬機(jī)對(duì)外發(fā)布開(kāi)始,開(kāi)發(fā)團(tuán)隊(duì)一直在努力試圖縮小 Java 與 C/C++ 語(yǔ)言在運(yùn)行效率上的差距。從實(shí)際的結(jié)果來(lái)看,確實(shí)成果顯著。OCv28資訊網(wǎng)——每日最新資訊28at.com

本文就來(lái)聊聊 HotSpot 虛擬機(jī)為了提升 Java 程序的執(zhí)行效率,都實(shí)現(xiàn)了哪些激動(dòng)人心的優(yōu)化技術(shù)。OCv28資訊網(wǎng)——每日最新資訊28at.com

二、JIT 編譯器的引入

JIT 編譯器,也稱(chēng)為即時(shí)編譯器,它是 JVM 的重要組成部分。與我們經(jīng)常用的生成 Java 字節(jié)碼的javac編譯器不同,JIT 編譯器是實(shí)現(xiàn) Java 程序執(zhí)行效率提升的核心利器。OCv28資訊網(wǎng)——每日最新資訊28at.com

經(jīng)常有面試官會(huì)提出這樣的一個(gè)問(wèn)題:Java 程序是解釋執(zhí)行還是編譯執(zhí)行?OCv28資訊網(wǎng)——每日最新資訊28at.com

剛開(kāi)始學(xué)習(xí) Java 的同學(xué),大概率會(huì)認(rèn)為 Java 是編譯執(zhí)行,其執(zhí)行流程類(lèi)似于如下圖。OCv28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片OCv28資訊網(wǎng)——每日最新資訊28at.com

源碼程序.java文件,通過(guò)javac命令編譯成.class字節(jié)碼,最后通過(guò)java命令在虛擬機(jī)中利用解釋器來(lái)執(zhí)行代碼。其中虛擬機(jī)的解釋器作用,就是將字節(jié)碼的操作指令和真正的平臺(tái)體系之間的指令建立映射,比如把 Java 的load指令轉(zhuǎn)換成native code的load指令,以此來(lái)完成程序的執(zhí)行。OCv28資訊網(wǎng)——每日最新資訊28at.com

其實(shí),準(zhǔn)確的說(shuō),Java 既有解釋執(zhí)行,也有編譯執(zhí)行,其工作流程大致可以用如下圖來(lái)描述。OCv28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片OCv28資訊網(wǎng)——每日最新資訊28at.com

其中,JIT 編譯器會(huì)將熱點(diǎn)代碼編譯成本地平臺(tái)相關(guān)的機(jī)器碼,并進(jìn)行各種層次的優(yōu)化,從而實(shí)現(xiàn)程序執(zhí)行效率的提升。OCv28資訊網(wǎng)——每日最新資訊28at.com

JIT 編譯器的出現(xiàn),可以說(shuō)補(bǔ)強(qiáng)了虛擬機(jī)邊運(yùn)行邊解釋的低性能問(wèn)題。OCv28資訊網(wǎng)——每日最新資訊28at.com

也許有的同學(xué)會(huì)提出這樣的疑問(wèn),既然引入了 JIT 編譯器可以顯著提升程序執(zhí)行效率,那 HotSpot 為什么不直接采用 JIT 編譯器來(lái)執(zhí)行呢?OCv28資訊網(wǎng)——每日最新資訊28at.com

簡(jiǎn)單的說(shuō),解釋器和編譯器各有優(yōu)勢(shì)。OCv28資訊網(wǎng)——每日最新資訊28at.com

  • 當(dāng)程序需要迅速啟動(dòng)和執(zhí)行時(shí),解釋器可以首先發(fā)揮作用,省去編譯的時(shí)間,可以立即執(zhí)行
  • 當(dāng)程序運(yùn)行后,隨著時(shí)間的推移,JIT 編譯器可以發(fā)揮作用,能把越來(lái)越多的代碼編譯成本地機(jī)器碼,進(jìn)一步提升程序的執(zhí)行效率

這就是為什么 Java 程序既有解釋執(zhí)行,也有編譯執(zhí)行的原因。OCv28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)然,能觸發(fā)即時(shí)編譯請(qǐng)求的條件比較多,比如方法調(diào)用,OSR 編譯請(qǐng)求等。在默認(rèn)設(shè)置下,無(wú)論是哪種場(chǎng)景,虛擬機(jī)在代碼編譯器還未完成的時(shí)候,都仍然按照解釋器來(lái)繼續(xù)執(zhí)行,而編譯動(dòng)作則是在后臺(tái)的編譯線程中運(yùn)行。OCv28資訊網(wǎng)——每日最新資訊28at.com

用戶可以通過(guò)-XX:-BackgroundCompilation參數(shù)來(lái)禁止后臺(tái)編譯,此時(shí)所有的編譯請(qǐng)求會(huì)等待,直到編譯完成后再開(kāi)始執(zhí)行本地機(jī)器碼。OCv28資訊網(wǎng)——每日最新資訊28at.com

2.1、Client 模式與 Server 模式

在 HotSpot 虛擬機(jī)中內(nèi)置了兩款即時(shí)編譯器,分別是Client Compiler和Server Compiler,也稱(chēng)為 C1 編譯器與 C2 編譯器。OCv28資訊網(wǎng)——每日最新資訊28at.com

在目前的 HotSpot 虛擬機(jī)中,默認(rèn)采用的是解釋器與其中一個(gè)即時(shí)編譯器直接配合的工作方式,用戶也可以使用-client或者-server參數(shù)來(lái)指定解釋器與具體的某個(gè)編譯器配合工作。OCv28資訊網(wǎng)——每日最新資訊28at.com

它們之間的區(qū)別,可以用如下內(nèi)容簡(jiǎn)要概括:OCv28資訊網(wǎng)——每日最新資訊28at.com

  • Client Compiler(C1編譯器):它是一個(gè)簡(jiǎn)單快速的編譯器,主要關(guān)注點(diǎn)在于局部性的優(yōu)化,而放棄了許多耗時(shí)間長(zhǎng)的全局優(yōu)化手段
  • Sever Compiler(C2編譯器):它是專(zhuān)門(mén)面向服務(wù)端的典型應(yīng)用并為服務(wù)端的性能配置特別調(diào)整過(guò)的編譯器,它會(huì)執(zhí)行所有經(jīng)典的優(yōu)化動(dòng)作,如無(wú)用代碼消除、循環(huán)展開(kāi)、常量傳播、基本塊重排序等,還會(huì)實(shí)施一些與 Java 語(yǔ)言特性密切相關(guān)的優(yōu)化技術(shù),如范圍檢查消除、空值檢查消除等,另外,還有可能根據(jù)解釋器或 Client Compiler 提供的性能監(jiān)控信息,進(jìn)行一些不穩(wěn)定的激進(jìn)優(yōu)化,如守護(hù)內(nèi)聯(lián)、分支頻率預(yù)測(cè)等

Sever Compiler 即時(shí)編譯器,無(wú)疑是比較緩慢的,但它的編譯速度依然遠(yuǎn)超傳統(tǒng)的靜態(tài)優(yōu)化編譯器,而且它相對(duì)于 Client Compiler 編譯器輸出的代碼質(zhì)量更高,可以減少本地代碼的執(zhí)行時(shí)間,從而抵消額外的編譯時(shí)間開(kāi)銷(xiāo),因此很多非服務(wù)端的虛擬機(jī)選擇-server模式來(lái)運(yùn)行。OCv28資訊網(wǎng)——每日最新資訊28at.com

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

在上文我們有提到,JIT 編譯器會(huì)將熱點(diǎn)代碼編譯成本地平臺(tái)相關(guān)的機(jī)器碼。OCv28資訊網(wǎng)——每日最新資訊28at.com

哪些代碼會(huì)被 JIT 編譯器判斷為“熱點(diǎn)代碼”呢?主要有兩類(lèi):OCv28資訊網(wǎng)——每日最新資訊28at.com

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

這兩種情況都會(huì)使即時(shí)編譯器以整個(gè)方法作為編譯對(duì)象。OCv28資訊網(wǎng)——每日最新資訊28at.com

比較難以理解的可能是第二種情況,對(duì)于被多次執(zhí)行的循環(huán)體,可以理解成以一個(gè)方法可能只被調(diào)用一次或者少量的幾次,但是方法體內(nèi)部存在循環(huán)次數(shù)較多的循環(huán)體問(wèn)題,這樣循環(huán)體的代碼也會(huì)被重復(fù)執(zhí)行多次,因此這些代碼也被認(rèn)為是“熱點(diǎn)代碼”。OCv28資訊網(wǎng)——每日最新資訊28at.com

上面提到的都是概念知識(shí),虛擬機(jī)如何判斷一段代碼是否是“熱點(diǎn)代碼”呢?主要有兩種辦法:OCv28資訊網(wǎng)——每日最新資訊28at.com

  • 基于采樣的熱點(diǎn)探測(cè)
  • 基于計(jì)數(shù)器的熱點(diǎn)探測(cè)

HotSpot 虛擬機(jī)中使用的是第二種基于計(jì)數(shù)器的熱點(diǎn)探測(cè)方法,它為每個(gè)方法準(zhǔn)備了兩類(lèi)計(jì)數(shù)器:方法調(diào)用計(jì)數(shù)器和回邊計(jì)數(shù)器。OCv28資訊網(wǎng)——每日最新資訊28at.com

在確認(rèn)虛擬機(jī)運(yùn)行參數(shù)的前提下,這兩類(lèi)計(jì)數(shù)器都有一個(gè)確認(rèn)的的閥值,當(dāng)計(jì)數(shù)器超過(guò)閥值時(shí),就會(huì)觸發(fā)即時(shí)編譯器。OCv28資訊網(wǎng)——每日最新資訊28at.com

下面我們一起來(lái)看看這兩類(lèi)計(jì)數(shù)器的實(shí)現(xiàn)。OCv28資訊網(wǎng)——每日最新資訊28at.com

2.2.1、方法調(diào)用計(jì)數(shù)器

方法調(diào)用計(jì)數(shù)器,通常用于統(tǒng)計(jì)方法被調(diào)用的次數(shù)。它的默認(rèn)閾值在Client模式下是 1500 次,在Server模式下是 10000 次,這個(gè)閾值可以通過(guò)-XX:CompileThreshold參數(shù)來(lái)人為設(shè)定。OCv28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)一個(gè)方法被調(diào)用時(shí),會(huì)檢查方法是否存在被 JIT 編譯過(guò)的版本,如果存在,則優(yōu)先使用編譯后的本地機(jī)器碼來(lái)執(zhí)行;如果不存在,將此方法的調(diào)用計(jì)數(shù)器值加 1,然后判斷方法調(diào)用計(jì)數(shù)器和回邊計(jì)數(shù)器之和是否超過(guò)方法調(diào)用計(jì)數(shù)器的閾值,如果超過(guò),向即時(shí)編譯器提交一個(gè)該方法的代碼編譯請(qǐng)求,在默認(rèn)不設(shè)置的情況下,不會(huì)同步等待編譯請(qǐng)求完成,而時(shí)直接以解釋方式執(zhí)行方法。OCv28資訊網(wǎng)——每日最新資訊28at.com

具體流程,可以用如下圖來(lái)概括。OCv28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片OCv28資訊網(wǎng)——每日最新資訊28at.com

如果不設(shè)置閥值的情況下,方法調(diào)用計(jì)數(shù)器統(tǒng)計(jì)的并不是方法被調(diào)用的絕對(duì)次數(shù),而是一個(gè)相對(duì)的執(zhí)行頻率,即一段時(shí)間之內(nèi)方法被調(diào)用的次數(shù)。OCv28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)超過(guò)一定的時(shí)間限制,如果方法的調(diào)用次數(shù)不足以讓它提交給即時(shí)編譯器編譯,那這個(gè)方法的調(diào)用計(jì)數(shù)器就會(huì)少一半,這個(gè)過(guò)程稱(chēng)為方法的調(diào)用計(jì)數(shù)器熱度衰減,而這段時(shí)間就稱(chēng)為此方法統(tǒng)計(jì)的半衰周期。OCv28資訊網(wǎng)——每日最新資訊28at.com

進(jìn)行熱度衰減的動(dòng)作是在虛擬機(jī)進(jìn)行垃圾回收時(shí)順便進(jìn)行的,可以通過(guò)-XX:-UseCounterDecay參數(shù)來(lái)關(guān)閉熱度衰減,讓方法計(jì)數(shù)器統(tǒng)計(jì)方法調(diào)用的絕對(duì)次數(shù),這樣一來(lái),只要系統(tǒng)運(yùn)行時(shí)間足夠長(zhǎng),基本上絕大部分方法都會(huì)被編譯成本地機(jī)器碼。OCv28資訊網(wǎng)——每日最新資訊28at.com

此外,用戶也可以通過(guò)-XX:CounterHalfLifeTime參數(shù)來(lái)設(shè)置半衰周期的時(shí)間,單位是秒。OCv28資訊網(wǎng)——每日最新資訊28at.com

2.2.2、回邊計(jì)數(shù)器

回邊計(jì)數(shù)器,通常用于統(tǒng)計(jì)一個(gè)方法中循環(huán)體代碼執(zhí)行的次數(shù)。在字節(jié)碼方法循環(huán)體中,遇到控制流向后跳轉(zhuǎn)的指令成為"回邊",這個(gè)過(guò)程會(huì)產(chǎn)生“棧上替換”的行為,也就是方法棧幀還在棧上,只是方法被替換了,HotSpot 把這個(gè)過(guò)程觸發(fā)的即時(shí)編譯,稱(chēng)之為 OSR 編譯。OCv28資訊網(wǎng)——每日最新資訊28at.com

關(guān)于回邊計(jì)數(shù)器的閾值設(shè)置,虛擬機(jī)沒(méi)有明確給出對(duì)應(yīng)的參數(shù),但是可以通過(guò)-XX:OnStackReplacePercentage參數(shù)來(lái)間接的調(diào)整回邊計(jì)數(shù)器的閾值,這個(gè)參數(shù)也稱(chēng)為 ORS 比率,回邊計(jì)數(shù)器的閾值計(jì)算公式如下:OCv28資訊網(wǎng)——每日最新資訊28at.com

  • Client 模式:方法調(diào)用計(jì)數(shù)器閾值 × OSR 比率 / 1000,其中 OSR 比率默認(rèn)值933,如果都取默認(rèn)值,回邊計(jì)數(shù)器的閾值應(yīng)該是 13995
  • Server 模式:方法調(diào)用計(jì)數(shù)器閾值 × ( OSR 比率 - 解釋器監(jiān)控比率) / 100,其中 OSR 比率默認(rèn) 140,解釋器監(jiān)控比率默認(rèn)33,如果都取默認(rèn)值,回邊計(jì)數(shù)器閾值應(yīng)該是 10700

當(dāng)解釋器遇到一條回邊指令時(shí),會(huì)先查找需要執(zhí)行的代碼片段中是否有已經(jīng)編譯的版本,如果有,會(huì)優(yōu)先執(zhí)行已編譯好的代碼;如果沒(méi)有,就會(huì)把回邊計(jì)數(shù)器的值加 1,然后判斷方法調(diào)用計(jì)數(shù)器和回邊計(jì)數(shù)器值之和是否超過(guò)回邊計(jì)數(shù)器的閾值,如果超過(guò),就會(huì)向即時(shí)編譯器提交一個(gè) OSR 編譯請(qǐng)求,并且把回邊計(jì)數(shù)器的值降低一些,以便繼續(xù)在解釋器中執(zhí)行循環(huán)。OCv28資訊網(wǎng)——每日最新資訊28at.com

具體流程,可以用如下圖來(lái)概括。OCv28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片OCv28資訊網(wǎng)——每日最新資訊28at.com

與方法計(jì)數(shù)器不同,回邊計(jì)數(shù)器沒(méi)有熱度衰減的過(guò)程,因此這個(gè)計(jì)數(shù)器統(tǒng)計(jì)的就是該方法循環(huán)執(zhí)行的絕對(duì)次數(shù),當(dāng)回邊計(jì)數(shù)器溢出的時(shí)候,虛擬機(jī)還會(huì)把方法計(jì)數(shù)器的值也調(diào)整成溢出狀態(tài),這樣下次再進(jìn)入該方法的時(shí)候,就會(huì)執(zhí)行標(biāo)準(zhǔn)的編譯過(guò)程。OCv28資訊網(wǎng)——每日最新資訊28at.com

三、運(yùn)行期優(yōu)化技術(shù)

HotSpot 虛擬機(jī)設(shè)計(jì)團(tuán)隊(duì)為了實(shí)現(xiàn)程序更快的執(zhí)行效率,列出了很多的優(yōu)化手段,比如方法內(nèi)聯(lián)、冗余訪問(wèn)消除、復(fù)寫(xiě)傳播、無(wú)用代碼消除、公共子表達(dá)式消除、數(shù)組邊界檢查消除、逃逸分析等。OCv28資訊網(wǎng)——每日最新資訊28at.com

下面我們抽取幾個(gè)最常見(jiàn)的優(yōu)化技術(shù),一起來(lái)看看相關(guān)的實(shí)現(xiàn)。OCv28資訊網(wǎng)——每日最新資訊28at.com

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

公共子表達(dá)式消除是一個(gè)普遍應(yīng)用于各種編譯器的經(jīng)典優(yōu)化技術(shù)。OCv28資訊網(wǎng)——每日最新資訊28at.com

如果一個(gè)子表達(dá)式已經(jīng)計(jì)算過(guò)了,且表達(dá)式中變量的值不曾發(fā)生變化,那么這個(gè)子表達(dá)式就可以當(dāng)做公共子表達(dá)式。OCv28資訊網(wǎng)——每日最新資訊28at.com

對(duì)于這種表達(dá)式,沒(méi)有必要再花時(shí)間去對(duì)它進(jìn)行計(jì)算,直接用前面計(jì)算過(guò)的表達(dá)式結(jié)果替代就可以了。如果這種優(yōu)化僅限于程序的基本塊內(nèi),便稱(chēng)為局部公共子表達(dá)式消除;如果這種優(yōu)化的范圍涵蓋了多個(gè)基本塊,便稱(chēng)為全局公共子表達(dá)式消除。OCv28資訊網(wǎng)——每日最新資訊28at.com

舉個(gè)簡(jiǎn)單的例子,假設(shè)存在以下代碼。OCv28資訊網(wǎng)——每日最新資訊28at.com

// 原始代碼int d = (c * b) * 12 + a + (a + b * c);

如果這段代碼交給 Javac 編譯器則不會(huì)進(jìn)行任何優(yōu)化,但是這段代碼進(jìn)入到虛擬機(jī)即時(shí)編譯器之后,它將會(huì)進(jìn)行如下優(yōu)化。OCv28資訊網(wǎng)——每日最新資訊28at.com

// 將 c*b 和 b*c 用 E 表示,消除公共子表達(dá)式int d = E * 12 + a + (a + E);

即時(shí)編譯器還可能進(jìn)行另一種叫做代數(shù)簡(jiǎn)化的優(yōu)化,把表達(dá)式變?yōu)椋?span style="display:none">OCv28資訊網(wǎng)——每日最新資訊28at.com

// 代數(shù)簡(jiǎn)化int d = E * 13 + a + a;

表達(dá)式變換之后,再次計(jì)算可以節(jié)省一些時(shí)間。OCv28資訊網(wǎng)——每日最新資訊28at.com

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

數(shù)組邊界檢查消除也是一個(gè)經(jīng)典優(yōu)化技術(shù)。OCv28資訊網(wǎng)——每日最新資訊28at.com

Java 語(yǔ)言作為一門(mén)動(dòng)態(tài)安全的語(yǔ)言,會(huì)自動(dòng)對(duì)數(shù)組的讀寫(xiě)訪問(wèn)索引合法性做檢查,當(dāng)超出地址范圍,會(huì)拋出java.lang.ArrayIndexOutOfBoundsException異常,這對(duì)軟件開(kāi)發(fā)很友好,但對(duì) JVM 卻是一個(gè)性能負(fù)擔(dān)。OCv28資訊網(wǎng)——每日最新資訊28at.com

如果能在編譯期根據(jù)數(shù)據(jù)流分析判定索引一直在數(shù)組邊界內(nèi),就可以消除數(shù)組上下邊界的檢測(cè),從而節(jié)省很多次條件判斷操作。OCv28資訊網(wǎng)——每日最新資訊28at.com

類(lèi)似的消除手段還有空指針檢查(NullPointException)、除數(shù)為零檢查(ArithmeticException)、自動(dòng)裝箱消除(Autobox Elimination)、安全點(diǎn)消除(Safepoint Elimination)、消除反射(Dereflection)等等,針對(duì)這些檢查的消除方式,可能會(huì)采用隱式異常處理的思路。OCv28資訊網(wǎng)——每日最新資訊28at.com

舉個(gè)簡(jiǎn)單的例子,假設(shè)存在以下代碼。OCv28資訊網(wǎng)——每日最新資訊28at.com

// 原始偽代碼if(foo != null) {    return foo.value;} else {    throw new NullPointException();}

優(yōu)化后的偽代碼。OCv28資訊網(wǎng)——每日最新資訊28at.com

// 隱式異常消除后的偽代碼try {    return foo.value;} catch (segment_fault) {    uncommon_trap();}

JVM 會(huì)注冊(cè)一個(gè) Segment Fault 信號(hào)的異常處理器(uncommon_trap() 是一個(gè)針對(duì)進(jìn)程層面的異常處理器,與 try-catch 的線程級(jí)異常處理器不同),當(dāng) foo 不為空,可以省去判空的開(kāi)銷(xiāo);如果 foo 真為空,會(huì)轉(zhuǎn)到異常處理器恢復(fù)中斷并拋出NullPointException異常。OCv28資訊網(wǎng)——每日最新資訊28at.com

借助 JVM 在運(yùn)行期收集的性能監(jiān)控信息,判定 foo 極少為空時(shí),采用這樣的優(yōu)化方式可以提升程序的執(zhí)行效率。OCv28資訊網(wǎng)——每日最新資訊28at.com

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

方法內(nèi)聯(lián)是 JVM 最重要的優(yōu)化手段之一,它可以去除方法調(diào)用的成本(如減少建立棧幀等),為其它優(yōu)化建立了良好的基礎(chǔ)。OCv28資訊網(wǎng)——每日最新資訊28at.com

虛擬機(jī)如果探測(cè)到某個(gè)方法是熱點(diǎn)方法并且長(zhǎng)度不太長(zhǎng)時(shí),會(huì)進(jìn)行內(nèi)聯(lián),所謂的內(nèi)聯(lián)就是把方法內(nèi)代碼拷貝、粘貼到調(diào)用者的位置。OCv28資訊網(wǎng)——每日最新資訊28at.com

舉個(gè)例子!OCv28資訊網(wǎng)——每日最新資訊28at.com

public final static void method1(){    handleA();    handleB();}
public static void main(String[] args) {    handle1();    method1();    handle2();}

優(yōu)化之后可能變成:OCv28資訊網(wǎng)——每日最新資訊28at.com

public static void main(String[] args) {    handle1();    handleA();    handleB();    handle2();}

從效果上看,就是把method1()方法拷貝到main()方法中。未拷貝之前,優(yōu)化空間非常小,但是合并到一個(gè)方法之后,就有了很大的優(yōu)化空間了。OCv28資訊網(wǎng)——每日最新資訊28at.com

再比如下面這個(gè)例子!OCv28資訊網(wǎng)——每日最新資訊28at.com

private final  static int method1(final int i) {    return i * i;}
public static void main(String[] args) {    System.out.println(method1(10));}

優(yōu)化之后可能變成:OCv28資訊網(wǎng)——每日最新資訊28at.com

public static void main(String[] args) {    System.out.println(100);}

虛擬機(jī)還能夠進(jìn)行常量折疊(constant folding)的優(yōu)化,減少不必要的代碼執(zhí)行環(huán)節(jié),從而提升代碼執(zhí)行效率。OCv28資訊網(wǎng)——每日最新資訊28at.com

再次想到一個(gè)問(wèn)題,在 Java 編程規(guī)范里面,可能很多新人不能理解為什么推薦盡量將方法聲明為final?OCv28資訊網(wǎng)——每日最新資訊28at.com

我們知道 Java 是多態(tài)的特性,子類(lèi)既可以調(diào)用父類(lèi)方法,也可以重寫(xiě)父類(lèi)方法,編程方面靈活性非常高,這樣其實(shí)會(huì)導(dǎo)致一個(gè)問(wèn)題,編譯期間無(wú)法確定應(yīng)該使用哪一個(gè)方法,只有在運(yùn)行時(shí)才能確定,這就可能導(dǎo)致虛擬機(jī)很難對(duì)方法進(jìn)行內(nèi)聯(lián)操作。OCv28資訊網(wǎng)——每日最新資訊28at.com

但是如果將方法聲明為final,這些方法是無(wú)法被重寫(xiě),方法 A 調(diào)用方法 B 基本上是可以完全確定的,可以進(jìn)行方法內(nèi)聯(lián)操作。OCv28資訊網(wǎng)——每日最新資訊28at.com

3.4、逃逸分析

逃逸分析,在之前對(duì)象內(nèi)存分配的文章中有所簡(jiǎn)單的介紹過(guò),我們?cè)俅位仡櫼幌孪嚓P(guān)的知識(shí)。OCv28資訊網(wǎng)——每日最新資訊28at.com

逃逸分析是一項(xiàng)比較前沿的優(yōu)化技術(shù),它并不是直接優(yōu)化代碼的手段,而是為其它優(yōu)化手段提供了分析技術(shù)。OCv28資訊網(wǎng)——每日最新資訊28at.com

逃逸分析的基本行為是分析對(duì)象動(dòng)態(tài)作用域。OCv28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)一個(gè)對(duì)象在方法里面被定義后,它可能被外部方法所引用,例如作為調(diào)用參數(shù)傳遞到其他方法中,這種稱(chēng)為方法逃逸;甚至還有可能被外部線程訪問(wèn)到,譬如賦值給可以在其他線程中訪問(wèn)的實(shí)例變量,這種稱(chēng)為線程逃逸。OCv28資訊網(wǎng)——每日最新資訊28at.com

如果能證明一個(gè)對(duì)象不會(huì)逃移到方法外或者線程之外,換句話說(shuō)就是別的方法或線程無(wú)法通過(guò)任何途徑訪問(wèn)到這個(gè)對(duì)象,則可以通過(guò)一些途徑為這個(gè)變量進(jìn)行一些不同程度的優(yōu)化。OCv28資訊網(wǎng)——每日最新資訊28at.com

3.4.1、棧上分配

在之前的對(duì)象創(chuàng)建文章中,我們提及過(guò),對(duì)象會(huì)優(yōu)先在堆上分配,垃圾收集器會(huì)定期回收堆空間中不再使用的對(duì)象,但這塊的內(nèi)存回收很耗時(shí)。如果確定一個(gè)對(duì)象不會(huì)逃逸出方法之外,讓這個(gè)對(duì)象在棧上分配,對(duì)象所占用的內(nèi)存空間就可以隨著棧幀出棧而銷(xiāo)毀,這樣垃圾收集器的壓力將會(huì)小很多。OCv28資訊網(wǎng)——每日最新資訊28at.com

3.4.2、同步消除

線程同步本身是一個(gè)相對(duì)耗時(shí)的過(guò)程,如果逃逸分析能夠確定一個(gè)變量不會(huì)逃逸出線程,無(wú)法被其他線程訪問(wèn),那么這個(gè)變量的讀寫(xiě)肯定就不會(huì)有競(jìng)爭(zhēng),此時(shí)虛擬機(jī)會(huì)對(duì)這個(gè)變量,實(shí)施的同步措施進(jìn)行消除。OCv28資訊網(wǎng)——每日最新資訊28at.com

比如你定義的類(lèi)的方法上有同步鎖,但在運(yùn)行時(shí),卻只有一個(gè)線程在訪問(wèn),此時(shí)逃逸分析后,虛擬機(jī)會(huì)去掉同步鎖來(lái)運(yùn)行。OCv28資訊網(wǎng)——每日最新資訊28at.com

3.4.3、標(biāo)量替換

標(biāo)量是指一個(gè)數(shù)據(jù)已經(jīng)無(wú)法再分解成更小的數(shù)據(jù)來(lái)表示了,比如 Java 虛擬機(jī)中的原始數(shù)據(jù)類(lèi)型(int,long 等數(shù)值類(lèi)型以及 reference 類(lèi)型)等都不能進(jìn)一步分解,它們可以稱(chēng)為標(biāo)量。相對(duì)的,如果一個(gè)數(shù)據(jù)可以繼續(xù)分解,那它稱(chēng)為聚合量。OCv28資訊網(wǎng)——每日最新資訊28at.com

Java 中最典型的聚合量是對(duì)象,如果逃逸分析證明一個(gè)對(duì)象不會(huì)被外部訪問(wèn),并且這個(gè)對(duì)象是可分解的,那程序真正執(zhí)行的時(shí)候?qū)⒖赡懿粍?chuàng)建這個(gè)對(duì)象,而改為直接創(chuàng)建它的若干個(gè)被這個(gè)方法使用到的成員變量來(lái)代替,拆散后的變量便可以被單獨(dú)分析與優(yōu)化,可以各自分別在棧幀或寄存器上分配空間,原本的對(duì)象就無(wú)需整體分配空間了。OCv28資訊網(wǎng)——每日最新資訊28at.com

關(guān)于逃逸分析的論文早在 1999 年就已經(jīng)發(fā)表,但直到 Sun JDK1.6 才實(shí)現(xiàn)了逃逸分析,直到現(xiàn)在這項(xiàng)優(yōu)化尚未足夠成熟,仍有很大改進(jìn)余地。OCv28資訊網(wǎng)——每日最新資訊28at.com

不成熟的原因主要是不能保證逃逸分析的性能收益必定能高于它的消耗。雖然在實(shí)際測(cè)試結(jié)果中,實(shí)施逃逸分析后的程序往往能運(yùn)行出不錯(cuò)的成績(jī),但是在實(shí)際的應(yīng)用程序,尤其是大型程序中反而發(fā)現(xiàn)實(shí)施逃逸分析可能出現(xiàn)效果不穩(wěn)定的情況,或因分析過(guò)程耗時(shí)但卻無(wú)法有效判別出非逃逸對(duì)象而導(dǎo)致性能有所下降。OCv28資訊網(wǎng)——每日最新資訊28at.com

如果有需要并且確認(rèn)對(duì)程序運(yùn)行有益,用戶可以使用-XX:+DoEscapeAnalysis參數(shù)來(lái)手動(dòng)開(kāi)啟逃逸分析,開(kāi)啟之后可以通過(guò)-XX:+PrintEscapeAnalysis參數(shù)來(lái)查看分析結(jié)果,用戶還可以使用-XX:+EliminateAllocations參數(shù)來(lái)開(kāi)啟標(biāo)量替換,使用-XX:+EliminatLocks參數(shù)來(lái)開(kāi)啟同步消除,使用-XX:+PrintEliminateAllocations參數(shù)查看標(biāo)量的替換情況。OCv28資訊網(wǎng)——每日最新資訊28at.com

四、小結(jié)

本文主要圍繞 JVM 在運(yùn)行期對(duì)代碼采取的一些優(yōu)化手段,進(jìn)行了一次知識(shí)內(nèi)容整合和總結(jié),希望能幫助到大家。OCv28資訊網(wǎng)——每日最新資訊28at.com

內(nèi)容比較多,如果有描述不對(duì)的地方,歡迎留言指出,不勝感激。OCv28資訊網(wǎng)——每日最新資訊28at.com

五、參考

1.https://www.cnblogs.com/xrq730/p/4857820.htmlOCv28資訊網(wǎng)——每日最新資訊28at.com

2.https://juejin.cn/post/7236634386568527928OCv28資訊網(wǎng)——每日最新資訊28at.com

3.https://blog.csdn.net/ChaoMing_H/article/details/129179684OCv28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-76550-0.html淺談JVM運(yùn)行期的幾種優(yōu)化手段

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: Python秘訣:Xmltodict,處理XML數(shù)據(jù)的終極利器

下一篇: 常說(shuō)的BFC是什么?如何觸發(fā)?

標(biāo)簽:
  • 熱門(mén)焦點(diǎn)
  • JavaScript學(xué)習(xí) -AES加密算法

    引言在當(dāng)今數(shù)字化時(shí)代,前端應(yīng)用程序扮演著重要角色,用戶的敏感數(shù)據(jù)經(jīng)常在前端進(jìn)行加密和解密操作。然而,這樣的操作在網(wǎng)絡(luò)傳輸和存儲(chǔ)中可能會(huì)受到惡意攻擊的威脅。為了確保數(shù)據(jù)
  • 深度探索 Elasticsearch 8.X:function_score 參數(shù)解讀與實(shí)戰(zhàn)案例分析

    在 Elasticsearch 中,function_score 可以讓我們?cè)诓樵兊耐瑫r(shí)對(duì)搜索結(jié)果進(jìn)行自定義評(píng)分。function_score 提供了一系列的參數(shù)和函數(shù)讓我們可以根據(jù)需求靈活地進(jìn)行設(shè)置。近期
  • 從零到英雄:高并發(fā)與性能優(yōu)化的神奇之旅

    作者 | 波哥審校 | 重樓作為公司的架構(gòu)師或者程序員,你是否曾經(jīng)為公司的系統(tǒng)在面對(duì)高并發(fā)和性能瓶頸時(shí)感到手足無(wú)措或者焦頭爛額呢?筆者在出道那會(huì)為此是吃盡了苦頭的,不過(guò)也得
  • 每天一道面試題-CPU偽共享

    前言:了不起:又到了每天一到面試題的時(shí)候了!學(xué)弟,最近學(xué)習(xí)的怎么樣啊 了不起學(xué)弟:最近學(xué)習(xí)的還不錯(cuò),每天都在學(xué)習(xí),每天都在進(jìn)步! 了不起:那你最近學(xué)習(xí)的什么呢? 了不起學(xué)弟:最近在學(xué)習(xí)C
  • 東方甄選單飛:有些鳥(niǎo)注定是關(guān)不住的

    文/彭寬鴻編輯/羅卿東方甄選創(chuàng)始人俞敏洪帶隊(duì)的“7天甘肅行”直播活動(dòng)已在近日順利收官。成立后一年多時(shí)間里,東方甄選要脫離抖音自立門(mén)戶的傳聞不絕于耳,“7
  • 年輕人的“職場(chǎng)羞恥感”,無(wú)處不在

    作者:馮曉亭 陶 淘 李 欣 張 琳 馬舒葉來(lái)源:燃次元“人在職場(chǎng),應(yīng)該選擇什么樣的著裝?”近日,在網(wǎng)絡(luò)上,一個(gè)與著裝相關(guān)的帖子引發(fā)關(guān)注,在該帖子里,一位在高級(jí)寫(xiě)字樓亞洲金
  • 阿里瓴羊One推出背后,零售企業(yè)迎數(shù)字化新解

    作者:劉曠近年來(lái)隨著數(shù)字經(jīng)濟(jì)的高速發(fā)展,各式各樣的SaaS應(yīng)用服務(wù)更是層出不窮,但本質(zhì)上SaaS大多局限于單一業(yè)務(wù)流層面,對(duì)用戶核心關(guān)切的增長(zhǎng)問(wèn)題等則沒(méi)有提供更好的解法。在Saa
  • 聯(lián)想小新Pad Pro 12.6將要推出,搭載高通驍龍 870 處理器

    聯(lián)想小新Pad Pro 12.6將于秋季新品會(huì)上推出,官方按照慣例直接在發(fā)布會(huì)前給出了機(jī)型的所有參數(shù)。聯(lián)想小新 Pad Pro 12.6 將搭載高通驍龍 870 處理器,重量為 5
  • 利用職權(quán)私自解除被封帳號(hào) Meta開(kāi)除20多名員工

    11月18日消息,據(jù)外媒援引知情人士表示,過(guò)去一年時(shí)間內(nèi),F(xiàn)acebook母公司Meta解雇或處罰了20多名員工以及合同工,指控這些人通過(guò)內(nèi)部系統(tǒng)以不當(dāng)方式重置用戶帳號(hào),其
Top 主站蜘蛛池模板: 延庆县| 合川市| 阜平县| 广宗县| 泸西县| 榆社县| 清水河县| 当雄县| 东光县| 郓城县| 浑源县| 衡东县| 定日县| 沙洋县| 新巴尔虎左旗| 清新县| 道真| 保定市| 阿坝| 长泰县| 古丈县| 满城县| 亚东县| 花垣县| 霍林郭勒市| 陵川县| 桦甸市| 错那县| 祥云县| 老河口市| 平武县| 东明县| 新巴尔虎左旗| 芦山县| 隆尧县| 平舆县| 庆元县| 甘孜县| 巴彦县| 东莞市| 水富县|