JIT即時編譯器指定使用C1和C2


參數設置

hotspot jvm 內置了兩個jit編譯器,分別是client compiler(C1編譯器)和server compiler(C2編譯器),可通過下列指令顯式指定使用哪種即時編譯器

 -client 指定java虛擬機運行在client模式下,並使用C1編譯器;

  特點:C1編譯器會堆字節碼進行簡單和可靠的優化,耗時短。以達到更快的編譯速度。

-server 指定java虛擬機運行在server模式下,並使用C2編譯器。

  特點:C2進行較長時間的優化,以及激進優化。但優化的代碼執行效率更高。

 

C1和C2編譯器的優化策略不同

  C1主要有方法內聯,去虛擬化冗余消除

    方法內聯:將引用函數代碼編譯到引用點處,這樣可以減少棧幀的生成,減少參數傳遞以及跳轉過程

    去虛擬化:對唯一的實現類進行內聯

    冗余消除:在運行期間,把一些不會運行的代碼折疊掉

  C2的優化主要是在全局層面,逃逸分析是優化的基礎,基於逃逸分析在C2上有如下幾種優化

    標量替換:用標量值替換聚合對象的屬性值

    棧上分配:對於未逃逸的對象分配對象在棧而不是堆

    同步消除:清除同步操作,通常指synchronized

  分層編譯策略:

    程序解釋執行(不開啟性能監控)可以觸發C1編譯,將字節碼編譯成機器碼,可以進行簡單優化,也可以加上性能監控,C2編譯會根據性能監控信息進行激進優化。

    當顯式指定了-server   時,默認開啟分層編譯策略,由C1編譯器和C2編譯器相互協作共同來執行編譯任務。

 

此外:

  在JDK10 之后Hotspot又加入了一個全新即時編譯器:Graal編譯器,目前處於實踐狀態

    可以通過-XX:+UnlockExperimentalVMOptions   -XX:+UseJVMCICompiler 去激活,才可以使用

  JDK9版本引入了AOT編譯器(Ahead of time compiler 靜態提前編譯器)

    AOT編譯工具jaotc,它借助Graal編譯器,將所輸入的java類文件轉換成機器碼,並存放至生成動態共享庫之中

    所謂的AOT編譯,是與即時編譯相對立的一個概念,即時編譯指的是在程序的運行過程中,將字節碼轉換為可在硬件上直接運行的機器碼,並部署至托管環境中的過程,而AOT編譯指的是,在程序運行前,,便將字節碼轉換為機器碼的過程;

    好處:

      java虛擬機加載已經與編譯成二進制庫,可以直接運行。不必等即時編譯器的預熱,減少java應用第一次運行慢的體驗

    缺點:

      破壞了java“一次編譯到處運行”,必須為每個不同硬件,os編譯對應的發行包

      降低了java鏈接過程的動態性,加載的代碼在編譯器就全部已知;

      還需要繼續優化中,最初只支持Linux X64 java base


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM