對Java平臺的理解?Java是解釋執行?

談談你對Java平臺的理解?“Java是解釋執行”,這句話正確嗎?

典型回答

Java本身是一種面向對象的語言,最顯著的特性有兩個方面,一是所謂的“一次書寫,到處運行”(Write once,run anywhere),能夠非常容易的獲得跨平臺能力;另外就是垃圾收集(GC),Java通過垃圾收集器回收分配內存,大部分情況下,程序猿不需要自己操心內存的分配和回收。

我們日常會接觸到JRE或者JDK。JRE即Java運行環境,包含了JVM和Java類庫,以及一些模塊等。而JDK可以看做是JRE的一個超集,提供了更多工具,比如編譯器、各種診斷工具等。

對于“Java是解釋執行”這句話,這個說法不太準確。我們開發的Java源代碼,首先通過Javac編譯成字節碼,然后在運行時,通過JVM內嵌的解釋器將字節碼轉換為最終的機器碼。但是常見的JVM,比如我們大多數情況下使用的Oracle JDK提供的Hotspot JVM,都提供了JIT(Just -In -Time)編譯器,也就是通常所說的動態編譯器,JIT能夠在運行時將熱點代碼編譯成機器碼,這種情況下部分熱點代碼就屬于編譯執行,而不是解釋執行了。

知識擴展

對于Java平臺的理解,可以從很多方面簡明扼要的談一下,例如:Java語言特性,包括泛型、Lambda等語言特性;基礎類庫,包括集合、IO/NIO、網絡、并發、安全等基礎類庫。

或者談談JVM的一些基礎概念和機制,比如類加載機制、垃圾收集的基本原理等等。

當然還有JDK包含的一些工具如編譯器、運行時環境、安全工具、診斷和監控工具等等。

然后再回到解釋執行和編譯執行的問題。

眾所周知,我們通常把Java分為編譯器和運行時,這里說的Java編譯和C/C++是有著不同的意義的,Javac的編譯,編譯Java源碼生成字節碼,而不是可以直接執行的機器碼。Java通過字節碼和JVM這種跨平臺的抽象,屏蔽了操作系統和硬件的細節,這也是實現“一次編寫,到處執行”的基礎。

在運行時,JVM會通過類加載器加載字節碼,解釋或者編譯執行。在主流的Java版本中,如JDK8實際是解釋和編譯混合的一種模式,即所謂的混合模式(-Xmixed)。通常運行在Server模式的JVM,會進行上萬次調用以收集足夠的信息進行高效的編譯,client模式這個門限是1500次。Oracle Hotspot JVM內置了兩個不同的JIT compiler,C1對應前面說的client模式,適用于對于啟動速度敏感的應用,比如普通的Java桌面應用;C2對應server模式,它的優化是為長時間運行的服務器端應用設計的。默認采用所謂的分層編譯。

Java虛擬機啟動時,可以指定不同的參數對運行模式進行選擇。比如,指定“-Xint”,就是告訴JVM只進行解釋執行,不對代碼進行編譯,這種模式拋棄了JIT可能帶來的性能優勢。畢竟解釋器是逐條讀入,逐條解釋運行的。與其相對應的,還有一個“-Xcomp”參數,這是告訴JVM關閉解釋器,不要進行解釋執行,或者叫做最大優化級別。那這種模式是不是高效呢?簡單來說,還真未必。“-Xcomp”會導致JVM啟動變慢非常多。

除了我們日常最常見的Java使用模式,其實還有一種新的編譯方式,即所謂的AOT(Ahead -of - Time),直接將字節碼編譯成機器代碼,這樣就避免了JIT預熱等各方面的開銷,比如Oracle JDK 9就引入了實驗性的AOT特性。

另外,JVM作為一個強大的平臺,不僅僅只有Java語言可以運行在JVM上,本質上合規的字節碼都可以運行,Java語言自身也為此提供了便利,可以看到類似Scala、Groovy等大量JVM語言,活躍在不同的場景。

更多聲音

Java的跨平臺特性與JVM的存在密不可分。Java語言本身與其他編程語言沒有特別大的差異,也不是說Java語言可以跨平臺,而是在不同的平臺都有可以讓Java語言運行的環境而已,所有才有了一些編寫,到處運行的說法。

程序從源代碼到運行的三個階段:編碼 --- 編譯 --- 運行 ---- 調試。Java在編譯階段則體現了跨平臺的特點。編譯過程大概是這樣的:首先將Java源代碼轉化為.class文件字節碼,這是第一次編譯。.class文件就是可以到處運行的文件,然后java字節碼會被轉化為目標機器碼,這是由JVM來執行的,即Java的第二次編譯。

“到處運行”的關鍵和前提在于JVM。因為在第二次編譯中JVM起著關鍵性作用,在可以運行Java虛擬機的地方都內含一個JVM操作系統。從而使Java提供了各種不同平臺上的虛擬機制,因此實現了“到處運行”的效果。

C/C++編程是面向操作系統的,需要開發者極大的關系不同操作系統之間的差異性;而Java平臺通過虛擬機屏蔽了操作系統的底層細節,使得開發者不需過多關注不同操作系統之間的差異性。

通過一個間接的中間層來進行解耦,是計算機領域非常常用的一種藝術手法,虛擬機是這樣,操作系統是這樣,HTTP也是這樣。

寫個程序直接執行字節碼就是解釋執行;寫個程序運行時把字節碼動態翻譯成機器碼就是JIT;寫個程序把Java源代碼直接翻譯成機器碼就是AOT;造個CPU直接執行字節碼,字節碼就是機器碼。

解釋執行和編譯執行的區別,類別一下,一個是同聲傳譯,一個是放錄音。

參考

以上都是參考自談談你對Java平臺的理解?

越讀越有味道的文章。

Android層面的擴展

上面提到了JIT和AOT,實際上這也是ART虛擬機與Dalvik虛擬機之間的區別。

Dalvik是Google設計用于Android平臺的Java虛擬機。Dalvik與JVM之間最大的區別在于虛擬機架構不同。JVM基于棧架構,程序在運行時虛擬機需要頻繁的從棧上讀寫數據,這個過程需要更多的指令分配和內存訪問次數,會耗費不少CPU時間,而且對于手機設備這種資源有限的條件下。是相當一大筆開銷。Dalvik基于寄存器架構,數據訪問通過寄存器直接傳遞,這樣的訪問方式比基于棧方式要快很多。

ART即Android Runtime,其處理應用程序執行的方式完全不同于Dalvik,Dalvik是依靠一個JIT編譯器去解釋字節碼。開發者編譯后的應用代碼需要通過一個解釋器在用戶設備上運行,這一機制并不高效,但能讓應用更容易的在不同硬件和架構上運行。ART則完全改變了這套做法,在應用安裝時就預編譯字節碼到機器碼,這一機制就是AOT編譯。在移除解釋代碼這一過程中,應用程序執行將更有效率,啟動更快。

ART優點:

  1. 系統性能顯著提升
  2. 應用啟動更快、運行更快、體驗更加流暢、觸摸反饋更加及時
  3. 更長的電池續航能力
  4. 支持更低的硬件

ART缺點:

  1. 更大的存儲空間占用,可能會增加10%-20%
  2. 更長的應用安裝時間
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。