日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

运行期优化

發布時間:2025/4/16 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 运行期优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、概述

即時編譯器(Just In Time Compiler,JIT編譯器):Java程序最初是通過解釋器進行解釋執行的,當虛擬機發現某個方法或代碼塊的運行
特別頻繁時,就會把這些代碼認定為“熱點代碼”。為了提高熱點代碼的執行效率,在運行時,虛擬機將會把這些代碼編譯成與本地平臺相關
的機器碼,并進行各種層次的優化,完成這個任務的編譯器稱為即時編譯器。

二、HotSpot虛擬機內的即時編譯器

1、解釋器與編譯器

當程序需要迅速啟動和執行的時候,解釋器可以首先發揮作用,省去編譯時間立即執行。
在程序運行后,隨時間推移,編譯器逐漸發揮作用,把越來越多的代碼編譯成本地代碼之后,可以提供執行效率。

HotSpot虛擬機中內置兩個即時編譯器,分別稱為Client Compiler 和Server Compiler,簡稱C1編譯器和C2編譯器。
默認C1編譯器,可以使用-client 或 -server 指定。
解釋器與編譯器搭配使用的方式在虛擬機中稱為混合模式,用戶可以通過參數-Xint強制虛擬機運行與解釋模式(Interpreted Mode),
這時編譯器完全不參與工作,全部代碼都使用解釋方式執行。
也可以使用-Xcomp強制虛擬機運行編譯模式(Compiled Mode),這時將優先采用編譯方式執行程序。
Client Compiler 可以獲得更高的編譯速度,Server Compiler可以獲得更好的編譯質量。

2、編譯對象與觸發條件u

熱點代碼:

  • 被多次調用的方法
  • 被多次執行的循環體

    判斷一段代碼是不是熱點代碼,是不是需要觸發即時編譯,這樣的行為稱為熱點探測。熱點探測方式:

  • 基于采樣的熱點探測:虛擬機周期性的檢查各個線程的棧頂,如果發現某個方法經常出現在棧頂,那這個方法就是熱點方法。
  • 基于計數器的熱點探測:虛擬機為每個方法建立計數器,統計方法的執行次數,如果執行次數超過一定閾值,就認為是熱點方法。
    HotSpot采樣的是基于計數器的熱點探測,為每個方法準備兩類計數器:方法調用計數器、回邊計數器。

方法調用計數器:統計方法被調用的次數,Client模式下默認1500次,Server模式下默認10000次,可以通過虛擬機參數-XX:CompiledThreshold修改。
回邊計數器:統計一個方法中循環體代碼執行次數。

三、編譯優化技術

1、公共子表達式消除

如果一個表達式E已經計算過了,并且從先前的計算到現在E中所有的變量的值都沒有發生變化,那么E的這次出現就成為了公共子表達式。
對于這種表達式就沒有必要花時間對它進行計算,只需直接用前面計算過的表達式結果代替E就可以了。

int d = (c * b) * 12 + a + (a + b * c);int d = E * 12 + a + (a + E);

當這段代碼進入虛擬機即時編譯器編譯后,就變為了第二行代碼

2、數組邊界檢查消除

java 在訪問數組類型數據時會自動進行上下界范圍檢查,如果超出范圍將拋出ArrayIndexOutOfBoundsException,每次數據讀寫都帶有一次
隱含的條件判定,影響性能。對于循環體來說,如果編譯器可以判定循環變量取值范圍永遠在[0,length())之間,那在整個循環中就可以
把數組上下界檢查消除。

3、方法內聯

把目標的代碼復制到發起調用的方法中,避免發生真實的方法調用。
分析對象動態作用域:當一個對象在方法中被定義后,它可能被外部方法所引用,例如作為調用參數傳遞到其他方法中,稱為方法逃逸。
甚至可能被外部線程訪問到,譬如賦值給類變量或可以在其他線程中訪問的實例變量,稱為線程逃逸。
如果能證明一個對象不會逃逸到變量或線程外,也就是別的方法或線程無法通過任何途徑訪問到這個對象,則可能為為這個變量進行優化。

  • 棧上分配:java虛擬機中,在java堆上分配創建對象的內存空間,java堆中的對象對于各個線程都是共享可見的,只要持有這個對象的引用,
    就可以訪問堆中存儲的對象數據。虛擬機垃圾收集系統可以回收堆中不再使用的對象。

如果確定一個對象不會逃逸出方法之外,那讓這個對象在棧上分配,對象占用的內存就可以隨棧幀出棧而銷毀。

  • 同步消除:線程同步本身就是一個相對耗時的過程,如果逃逸分析能夠確定一個變量不會逃逸出線程,無法被其他線程訪問,那這個變量的讀寫
    肯定就不會有競爭,對這個變身實施同步措施也就可以消除。
  • 標量替換:標量是指一個數據已經無法分解成更小的數據來表示,Java虛擬機中的原始數據類型都不能再進一步分解,就可以稱為標量。
    相對的,如果一個數據可以繼續分解,稱為聚合量,java中的對象就是典型的聚合量。如果把一個Java對象拆散,根據程序訪問的情況,將其使用

到的成員變量恢復原始類型來訪問就叫標量替換。如果逃逸分析證明一個對象不會被外部訪問,并且對象可以被拆散的話, 程序真正執行的時候
可能不創建這個對象,而改為直接創建它的若干被這個方法使用到的成員變量替換。這些變量建立在棧上分配讀寫。

總結

以上是生活随笔為你收集整理的运行期优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。