JVM編譯優化

2021-10-07 04:02:08 字數 2474 閱讀 6779

參考文章:

整體描述:

標量替換:

虛擬機會用即時編譯器把執行頻繁的熱點**變成機器碼,並做相應優化。

1 直譯器和編譯器的優點

直譯器優點:

程式啟動快,占用記憶體小,編譯失敗時還能逆優化恢復到解析狀態

編譯器優點:

執行時可探測熱點**,並把位元組碼編譯成本地機器碼,這樣程式執行效率更高

2 在什麼情況下才會被判定為熱點**?需要編譯成機器碼了?

jvm啟動的時候只有直譯器進行解析,啟動完之後會根據執行狀態,然後依據執行模式(client、server模式,預設服務端預設都用server模式)來進行執行時編譯。

如何判斷為熱點**(多次呼叫的方法/迴圈體)

- 基於取樣熱點探測:

經常出現在棧頂,可判斷為熱點**,但對於迴圈體不好判斷

- 基於計數器熱點探測(hotspot就是用這種):

對呼叫次數加乙個計數器,呼叫方法(用 方法呼叫計數器)/迴圈體(應用 回邊計數器)此次到達上限,就會被編譯成機器碼。

備註:上面在沒編譯完成之前,都是用解析器執行位元組碼來執行程式,並且有些**編譯不成功就會退回用直譯器解析。

3 下面說下不同模式下編譯器做的優化

3.1 client模式(c1編譯器)優化

只針對耗時較高的做優化,佔記憶體小,主要有方法內聯、去虛擬化、冗餘消除等,做的區域性優化

1 方法內聯

多方法呼叫,引數傳來傳去,還要壓棧彈棧,這收他就把被呼叫的方法複製出來,避免頻繁彈棧出棧,例子如下:

*************************

int a(int val)

int b(int val)

優化後如下:

int a(int val)

*************************

其閾值設定引數如下:

-xx:compilethreshold

-- client,預設為1500;

-- server,預設為10000;

優化引數建議:

針對熱點方法,想要通過jit內聯優化來提公升效能的建議

1. 更小的方法體,jvm總是偏好更小的方法。

2. 盡量使用final、private、static修飾符,避免因為繼承而需要額外的型別檢查

3. 使用+printinlining引數校驗效果

2 去虛擬化

裝在.class的時候,發現類只有乙個實現類,那呼叫該類實現類的方法時,就直接進行內聯(對,就是1 的內聯 (╬▔皿▔)凸)來優化

3 冗餘消除

編譯時把多餘無用**摺疊或消除

3.2 server模式(c2編譯器)優化

占用記憶體多,大量優化,適合服務端,其優化有無用**消除、迴圈展開、迴圈表示式外提、消除公共子表示式、常量傳播、基本塊衝排序等,並且會做c1編譯器相關的優化

1 逃逸分析

c2優化的基礎,根據執行狀態來判斷方法中的變數是否會被外部讀取,如不會則認為此變數是不會逃逸的,那麼在編譯時會做標量替換、棧上分配和同步消除等優化。

- 方法逃逸:當前物件被外部方法引用

- 執行緒逃逸:當前物件被外部執行緒訪問

1.1 標量替換

替換為標量(基本的資料型別如int、long),通過標量替換將該物件分解,並在棧上分配記憶體

1.2 棧上分配

直接在棧上建立例項,而不用去堆上建立,這樣分配速度快,**方便

1.3 同步消除

如果發現物件不存在競爭,就會把他的鎖標識消除,這樣讀寫就不會有競爭

4 編譯期優化(早期優化)

優化語法糖,比如(不止三種):

1 泛型:編譯完成後替換為原生型別

2 條件編譯:比如發現必傳什麼值,就會把他預先處理好,如下:

if (false)

-- 比如上面發現if裡面必為false,就會直接消除掉這個**

3 自動裝箱/拆箱:會轉為基本資料型別

5 執行時優化(晚期優化)

hotspot採用解析器和編譯器並行策略,具體優化如下:

1 公共字表示式消除

發現這個表示式上面已經計算過了,下面直接用上面的結果值就行了,無需再次計算

2 陣列邊界檢查消除

發現**肯定不會越界,那直接不檢查邊界

3 方法內聯

4 逃逸分析

6 與c++比較

效能上比不過c++(因為他全是機器碼),但是可以做監控、熱點探測並且有選擇性地優化**

JVM 效能優化

最近發現服務cpu消耗不是很穩定,在150 600 之間不停跳動,以前沒有這種情況,check了一下,是old區記憶體不太夠導致每隔一小段時間cms gc了,old區記憶體不夠的主要原因是服務需要載入的資料變多了,使得old區頻繁gc 用 jmap heap pid 可以看到當old區佔比超過92 ...

jvm引數優化

堆記憶體優化 調整jvm啟動引數 xms xmx xx newsize xx maxnewsize,如調整初始堆記憶體和最大對記憶體 xms256m xmx512m。或者調整初始new generation的初始記憶體和最大記憶體 xx newsize 128m xx maxnewsize 128m...

jvm晚期優化

最具代表性的幾個優化技術 公共子表示式消除描述 如果乙個表示式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陣列泛微檢查...