[Java 執行那些事] —— Java 是解釋執行麼?

這裏寫圖片描述

本文是《Java執行那些事》系列文章的第一篇,在閱讀文章之前,請您思考標題的內容:Java是解釋執行麼?

答案(刮開塗層有驚喜):【這句話說的並不準確,Java的執行是解釋+編譯混合的。你答對了麼?】(手機的朋友請到文尾)

#解釋執行與編譯執行

解釋執行描述的是將源語言直接作爲輸入,每次執行一條就將源代碼解釋成機器碼,並不保留中間結果。因爲每次都需要解釋所以移植性和跨平臺性很高。

我們可以將解釋執行的過程類比成現實生活中的高級翻譯——同聲傳譯。翻譯的工作就是將我們的語言翻譯成對方國家的語言,你說一句,翻譯就緊跟這翻譯這一句,無需等待。也就是說只要我們帶上足夠的翻譯,走遍全球都不是問題。

這裏寫圖片描述

而編譯執行描述的是將源代碼事先編譯成目標機器的機器碼文件,這樣一來就直接可以在目標機器上運行,但是由於目標機器的不同,每次更換目標都需要重新編譯與之相對的機器碼文件,所以移植性較差。

這個過程可以類比成將翻譯的結果錄製成磁帶,好處就是你可以直接播放磁帶讓對方聽得懂,不必隨身帶翻譯了。但是當你在美國的時候需要把語言翻譯成英語,而到了俄羅斯你就得再把你的語言翻譯成俄語,靈活度不高。

解釋執行是來一句翻譯一句,當然沒有編譯執行這樣直接執行的效率高,但是解釋執行靈活,可謂寫一次到處執行!!

#Java的執行過程
寫一次到處執行(write once run anywhere)其實是Java的宣傳語,這很容易讓人聯繫到解釋執行的低效問題,那麼Java的執行過程到底是怎麼樣的呢?

首先我們編寫好的Java代碼會通過JavaC編譯成字節碼文件(bytecode),在運行的時候,通過JVM內嵌的解釋器將字節碼文件解釋成機器碼。但是常見的JVM例如Hotspot虛擬機,都提供了JIN(just int time)機制,此機制被稱爲動態編譯機制,它可以將反覆執行的熱點代碼直接編譯成機器碼,這種情況下部分熱點代碼的執行就屬於編譯執行,而不是解釋執行了。

Hotspot JVM默認採用這種混合執行模式,綜合兩者優勢將靈活和執行速度合二爲一。

Java執行效率真的差麼

及時編譯的模式假定程序符合二八定律的,即百分之二十的代碼佔用了百分之八十的資源。對不常用的代碼,根本無需耗時將其編譯成機器碼,採用解釋執行完全可以滿足要求。而對於常用的熱點代碼,可以將其編譯成機器碼,達到理想的運行效率。

現在的Java程序其實是可以快過C++,因爲及時編譯是動態編譯,比C++事先編譯能拿到程序運行時的更多信息,可以進行更多的優化。

AOT

而且在Java9中引入了實驗室特徵 AOT(ahead of time compilation),AOT能夠在線下事先將java字節碼文件編譯成機器碼!!!。

但是對於那些發佈不頻繁,或者說長時間運行的的程序,其實在選擇線下編譯和及時編譯的效果一樣,因爲當程序運行一兩個小時之後,及時編譯已經基本完成,而且動態編譯可以獲取程序運行時的更多信息,優化效果更好。

不僅如此在主流Java版本中例如JDK8,提供了多種即時編譯器模式:Server、Client 和多種及時編譯器:C1、C2 和 Graal。

可見未來的Java性能超越C/C++已經不是夢想。

答案:【這句話說的並不準確,Java的執行是解釋+編譯混合的。你答對了麼?

文章的最後向您推薦兩個關於Java的專欄。專欄的內容有音頻有文稿, 無論是在路上還是業餘時間的學習都很有裨益。

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章