JAVA是解釋執行還是編譯執行的理解
“一次編譯、到處運行”說的是Java語言跨平臺的特性,Java的跨平臺特性與Java虛擬機的存在密不可分,可在不同的環境中運行。比如說Windows平臺和Linux平臺都有相應的JDK,安裝好JDK後也就有了Java語言的運行環境。其實Java語言本身與其他的編程語言沒有特別大的差異,並不是說Java語言可以跨平臺,而是在不同的平臺都有可以讓Java語言運行的環境而已,所以才有了Java一次編譯,到處運行這樣的效果。
嚴格的講,跨平臺的語言不止Java一種,但Java是較為成熟的一種。“一次編譯,到處運行”這種效果跟編譯器有關。編程語言的處理需要編譯器和解釋器。Java虛擬機和DOS類似,相當於一個供程序運行的平臺。
程序從源代碼到運行的三個階段:編碼——編譯——運行——調試。Java在編譯階段則體現了跨平臺的特點。編譯過程大概是這樣的:首先是將Java源代碼轉化成.CLASS文件字節碼,這是第一次編譯。.class文件就是可以到處運行的文件。然後Java字節碼會被轉化為目標機器代碼,這是是由JVM來執行的,即Java的第二次編譯。
“到處運行”的關鍵和前提就是JVM。因為在第二次編譯中JVM起著關鍵作用。在可以運行Java虛擬機的地方都內含著一個JVM操作系統。從而使JAVA提供了各種不同平臺上的虛擬機制,因此實現了“到處運行”的效果。
Java采用的是解釋和編譯混合的模式。它首先通過javac將源碼編譯成字節碼文件class.然後在運行的時候通過解釋器或者JIT將字節碼轉換成最終的機器碼。
單獨使用解釋器的缺點:
拋棄了JIT可能帶來的性能優勢。如果代碼沒有被JIT編譯的話,再次運行時需要重復解析。
單獨使用JIT的缺點:
需要將全部的代碼編譯成本地機器碼。要花更多的時間,JVM啟動會變慢非常多;
增加可執行代碼的長度(字節碼比JIT編譯後的機器碼小很多),這將導致頁面調度,從而降低程序的速度。
有些JIT編譯器的優化方式,比如分支預測,如果不進行profiling,往往並不能進行有效優化。
因此,HotSpot采用了惰性評估(Lazy Evaluation)的做法,根據二八定律,消耗大部分系統資源的只有那一小部分的代碼(熱點代碼),而這也就是JIT所需要編譯的部分。JVM會根據代碼每次被執行的情況收集信息並相應地做出一些優化,因此執行的次數越多,它的速度就越快。
JDK 9引入了一種新的編譯模式AOT(Ahead of Time Compilation),它是直接將字節碼編譯成機器碼,這樣就避免了JIT預熱等各方面的開銷。JDK支持分層編譯和AOT協作使用。
註:JIT為方法級,它會緩存編譯過的字節碼在CodeCache中,而不需要被重復解釋。
JAVA是解釋執行還是編譯執行的理解