jvm優化理解
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編譯時期就 可以將同步鎖去掉,以減少加鎖與解鎖造成的資源開銷。