jvm優化理解

it_bky發表於2021-11-10

jvm架構理解

 

jvm程式執行流程

 

 編譯器和直譯器協調工作流程

 

 在部分商用虛擬機器中(如HotSpot),java程式最初是通過直譯器進行解釋執行的,當虛擬機器發現某個方法或者某段程式碼執行的特別頻繁後就會把這些程式碼作為【熱點程式碼】,為了提高【熱點程式碼】的執行效率,在執行時,虛擬機器會把這些【熱點程式碼】編譯成為與本地平臺相關的【機器碼】,並進行各層次的優化,完成這個任務的編譯器成為即時編譯器(JTI)

JIT屬於動態編譯,是說在執行時進行編譯,與之相對的是靜態編譯(事前編譯),

熱點程式碼

1.多次被呼叫的方法;2.被多次執行的迴圈體

這兩種情況,編譯器都是以整個方法作為編譯物件。這種編譯方法因發生在執行過程中,因此被稱為【棧上替換】,即方法棧幀還在棧上,方法就被替換了。

熱點程式碼的檢測方式

1.基於取樣的熱點探測

  虛擬機器會週期性的檢測各個執行緒的棧頂,如果發現某個方法經常出現在棧頂,那麼就會將這個方法視為【熱點程式碼】。

2.基於計數器的熱點探測。

  虛擬機器回味每個方法建立計數器,統計方法的執行次數,如果計數器超過一定的【閥值】,就會認為這個方法為【熱點程式碼】

為什麼要使用直譯器和編譯器並存的架構

當程式需要快速啟動和執行的時候,直譯器首先起作用,省去了編譯的時間。在程式執行一段時間後,隨著時間的推移,編譯器發揮作用,把越來越多的程式碼編譯成原生程式碼,可以獲得更高的執行效率。

JIT優化

1.公共子表示式消除

如果一個表示式E已經計算過了,兵器從先前的計算到現在E中的所有變數的值都沒有發生變化,那麼E的這次出現就會成為【公共子表示式】,對於這種表示式,沒有必要花更多的時間對他進行計算,直接用前面的計算結果替代就可以了

int d = (c*b)*12+a+(a+b*c)  替換為int d = E*12+a+(a+E)   進一步代數化簡為int d = E*13+a*2;

2.方法內聯

將方法直接用方法體中的程式碼進行替換,這就是方法內聯,減少了方法呼叫過程中的壓棧和出棧開銷。

3.逃逸分析

逃逸分析的基本行為就是分析物件的作用域,當一個物件在方法中被定義後,如果沒有被該方法外引用,那麼就可以將該物件在棧上分配空間,也可以還在堆上分配空間,這樣就減少了垃圾回收。

4.標量替換

在JIT階段,如果經過逃逸分析,發現一個物件不會被外界訪問的話,那麼經過JIT優化,就會把這個對 象拆解成若干個其中包含的若干個成員變數來代替。

5.同步鎖消除

同樣基於逃逸分析,當加鎖的變數不會發生逃逸,是執行緒私有的完全沒有必要加鎖。 在JIT編譯時期就 可以將同步鎖去掉,以減少加鎖與解鎖造成的資源開銷。

 

相關文章