Java本身是一種面向物件的語言,最顯著的特性有兩個方面,一是所謂的“書寫一次,到處運行”,能夠非常容易地獲得跨平臺能力; 另外就是垃圾收集(GC),Java通過垃圾收集器(Garbage Collector)回收分配記憶體,大部分情況下,程式員不需要自己操心記憶體的分配和回收, 對于“Java是解釋執行”這句話,說法不太準確, 我們開發的Java的源代碼,首先通過Javac編譯成為位元組碼(bytecode),然后,在運行時,通過Java虛擬機(JVM)內嵌的解釋器將位元組碼解釋執行,轉換成為最終的機器碼, 但是常見的JVM,比如我們大多數情況使用的Oracle JDK提供的Hotspot JVM,都提供了JIT(Just-In-Time)編譯器,也就是通常所說的動態編譯器,JIT能夠在運行時將熱點代碼編譯成機器碼,這種情況下部分熱點代碼就屬于 編譯執行,而不是解釋執行了, Javac的編譯,編譯Java原始碼生成“.class”檔案里面實際是位元組碼,而不是可以直接執行的機器, Java通過位元組碼和Java虛擬機(JVM)這種跨平臺的抽象,屏蔽了作業系統和硬體的細節,這也是實作“一次編譯,到處執行”的基礎, 在運行時,JVM會通過類加載器(Class-Loader)加載位元組碼,解釋或者編譯執行, 主流Java版本中,如JDK 8實際是解釋和編譯混合的一種模式,即所謂的混合模式(-Xmixed), 通常運行在server模式的JVM,會進行上萬次呼叫以收集足夠的資訊進行高效的編譯,client模式這個門限是1500次, Oracle Hotspot JVM內置了兩個不同的JIT compiler,C1對應前面說的client模式,適用于對于啟動速度敏感的應用,比如普通Java桌面應用; C2對應server模式,它的優化是為長時間運行的服務器端應用設計的, 默認是采用所謂的分層編譯(TieredCompilation), Java虛擬機啟動時,可以指定不同的引數對運行模式進行選擇, 比如,指定“-Xint”,就是告訴JVM只進行解釋執行,不對代碼進行編譯,這種模式拋棄了JIT可能帶來的性能優勢,畢竟解釋器(interpreter)是逐條讀入,逐條解釋運行的, 與其相對應的,還有一個“-Xcomp”引數,這是告訴JVM關閉解釋器,不要進行解釋執行,或者叫作最大優化級別,那你可能會問這種模式是不是最高效啊?簡單說,還真未必,“-Xcomp”會導致JVM啟動變慢非常多,同時有些 JIT編譯器優化方式,比如分支預測,如果不進行profling,往往并不能進行有效優化, 除了我們日常最常見的Java使用模式,其實還有一種新的編譯方式,即所謂的AOT(Ahead-of-Time Compilation),直接將位元組碼編譯成機器代碼,這樣就避免了JIT預熱等各方面的開銷,比如 Oracle JDK 9就引入了實驗性的AOT特性,并且增加了新的jaotc工具, Java位元組碼的設計充分考慮了JIT這一即時編譯方式,可以將位元組碼直接編譯成高性能的本地機器碼,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/143472.html
標籤:Java
